refactoring

This commit is contained in:
Nick Fisher
2025-03-21 14:56:20 +08:00
parent 1177a71f73
commit 255c0edd49
38 changed files with 1521 additions and 1207 deletions

View File

@@ -31,8 +31,8 @@ class BackgroundImage extends ThermionAsset {
Future destroy() async {
Scene_removeEntity(scene.scene, entity);
await texture!.dispose();
await sampler!.dispose();
await texture?.dispose();
await sampler?.dispose();
await mi.destroy();
}
@@ -63,6 +63,10 @@ class BackgroundImage extends ThermionAsset {
await mi.setParameterFloat4("backgroundColor", r, g, b, a);
}
Future hideImage() async {
await mi.setParameterInt("showImage", 0);
}
///
///
///
@@ -317,4 +321,25 @@ class BackgroundImage extends ThermionAsset {
// TODO: implement updateBoneMatrices
throw UnimplementedError();
}
@override
Future<List<String>> getChildEntityNames() async {
return [];
}
@override
Future<bool> isCastShadowsEnabled({ThermionEntity? entity}) async {
return false;
}
@override
Future<bool> isReceiveShadowsEnabled({ThermionEntity? entity}) async {
return false;
}
@override
Future transformToUnitCube() {
// TODO: implement transformToUnitCube
throw UnimplementedError();
}
}

View File

@@ -21,7 +21,7 @@ Future<void> withVoidCallback2(Function() func) async {
completer.complete();
};
final nativeCallable = NativeCallable<Void Function()>.listener(callback);
RenderLoop_addTask(nativeCallable.nativeFunction);
RenderThread_addTask(nativeCallable.nativeFunction);
await completer.future;
nativeCallable.close();
}

View File

@@ -63,6 +63,24 @@ class FFIAsset extends ThermionAsset {
return children;
}
///
///
///
@override
Future<List<String?>> getChildEntityNames() async {
final childEntities = await getChildEntities();
var names = <String?>[];
for (final entity in childEntities) {
var name = NameComponentManager_getName(app.nameComponentManager, entity);
if (name == nullptr) {
names.add(null);
} else {
names.add(name.cast<Utf8>().toDartString());
}
}
return names;
}
///
///
///
@@ -392,14 +410,16 @@ class FFIAsset extends ThermionAsset {
///
///
///
Future<bool> isCastShadowsEnabled(ThermionEntity entity) async {
Future<bool> isCastShadowsEnabled({ThermionEntity? entity}) async {
entity ??= this.entity;
return RenderableManager_isShadowCaster(app.renderableManager, entity);
}
///
///
///
Future<bool> isReceiveShadowsEnabled(ThermionEntity entity) async {
Future<bool> isReceiveShadowsEnabled({ThermionEntity? entity}) async {
entity ??= this.entity;
return RenderableManager_isShadowReceiver(app.renderableManager, entity);
}

View File

@@ -70,8 +70,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
await FilamentApp.instance!.destroy();
}
RenderLoop_destroy();
RenderLoop_create();
RenderThread_destroy();
RenderThread_create();
final engine = await withPointerCallback<TEngine>((cb) =>
Engine_createRenderThread(
@@ -95,6 +95,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
final renderTicker = RenderTicker_create(renderer);
RenderThread_setRenderTicker(renderTicker);
final nameComponentManager = NameComponentManager_create();
FilamentApp.instance = FFIFilamentApp(
@@ -110,30 +112,34 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
config.resourceLoader);
}
final _views = <FFISwapChain, List<FFIView>>{};
final _viewMappings = <FFIView, FFISwapChain>{};
final _swapChains = <FFISwapChain, List<FFIView>>{};
final viewsPtr = calloc<Pointer<TView>>(255);
///
///
///
Future setRenderable(covariant FFIView view, bool renderable) async {
final swapChain = _viewMappings[view]!;
if (renderable && !_views[swapChain]!.contains(view)) {
_views[swapChain]!.add(view);
} else if (!renderable && _views[swapChain]!.contains(view)) {
_views[swapChain]!.remove(view);
}
await view.setRenderable(renderable);
await _updateRenderableSwapChains();
}
final views = calloc<Pointer<TView>>(255);
for (final swapChain in _views.keys) {
var numViews = _views[swapChain]!.length;
for (int i = 0; i < numViews; i++) {
views[i] = _views[swapChain]![i].view;
Future _updateRenderableSwapChains() async {
for (final swapChain in _swapChains.keys) {
final views = _swapChains[swapChain];
if (views == null) {
continue;
}
int numRenderable = 0;
for (final view in views) {
if (view.renderable) {
viewsPtr[numRenderable] = view.view;
numRenderable++;
}
}
RenderTicker_setRenderable(
renderTicker, swapChain.swapChain, views, numViews);
renderTicker, swapChain.swapChain, viewsPtr, numRenderable);
}
calloc.free(views);
}
@override
@@ -143,6 +149,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
if (hasStencilBuffer) {
flags |= TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
}
print("swapchain flags $flags");
final swapChain = await withPointerCallback<TSwapChain>((cb) =>
Engine_createHeadlessSwapChainRenderThread(
this.engine, width, height, flags, cb));
@@ -173,6 +180,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
Engine_destroySwapChainRenderThread(
engine, (swapChain as FFISwapChain).swapChain, callback);
});
_swapChains.remove(swapChain);
}
///
@@ -180,17 +188,21 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
///
@override
Future destroy() async {
for (final swapChain in _views.keys) {
for (final view in _views[swapChain]!) {
for (final swapChain in _swapChains.keys) {
if (_swapChains[swapChain] == null) {
continue;
}
for (final view in _swapChains[swapChain]!) {
await setRenderable(view, false);
}
}
for (final swapChain in _views.keys) {
for (final swapChain in _swapChains.keys.toList()) {
await destroySwapChain(swapChain);
}
RenderLoop_destroy();
RenderThread_destroy();
RenderTicker_destroy(renderTicker);
Engine_destroy(engine);
calloc.free(viewsPtr);
}
///
@@ -440,8 +452,24 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
///
@override
Future render() async {
await withVoidCallback(
(cb) => RenderTicker_renderRenderThread(renderTicker, 0, cb));
// await withVoidCallback(
// (cb) => RenderTicker_renderRenderThread(renderTicker, 0, cb));
final swapchain = _swapChains.keys.first;
final view = _swapChains[swapchain]!.first;
await withBoolCallback((cb) {
Renderer_beginFrameRenderThread(renderer, swapchain.swapChain, 0, cb);
});
await withVoidCallback((cb) {
Renderer_renderRenderThread(
renderer,
view.view,
cb,
);
});
await withVoidCallback((cb) {
Renderer_endFrameRenderThread(renderer, cb);
});
}
///
@@ -450,11 +478,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
@override
Future register(
covariant FFISwapChain swapChain, covariant FFIView view) async {
_viewMappings[view] = swapChain;
if (!_views.containsKey(swapChain)) {
_views[swapChain] = [];
if (!_swapChains.containsKey(swapChain)) {
_swapChains[swapChain] = [];
}
_views[swapChain]!.add(view);
_swapChains[swapChain]!.add(view);
await _updateRenderableSwapChains();
}
final _hooks = <Future Function()>[];
@@ -493,7 +521,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
completer.complete(true);
});
RenderLoop_requestAnimationFrame(callback.nativeFunction.cast());
RenderThread_requestAnimationFrame(callback.nativeFunction.cast());
try {
await completer.future.timeout(Duration(seconds: 1));
@@ -572,15 +600,20 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
Future<Uint8List> capture(covariant FFIView view,
{bool captureRenderTarget = false}) async {
final viewport = await view.getViewport();
final swapChain = _viewMappings[view];
final swapChain = _swapChains.keys
.firstWhere((x) => _swapChains[x]?.contains(view) == true);
final out = Uint8List(viewport.width * viewport.height * 4);
await withVoidCallback((cb) {
Engine_flushAndWaitRenderThead(engine, cb);
});
var fence = await withPointerCallback<TFence>((cb) {
Engine_createFenceRenderThread(engine, cb);
});
await withBoolCallback((cb) {
Renderer_beginFrameRenderThread(renderer, swapChain!.swapChain, 0, cb);
Renderer_beginFrameRenderThread(renderer, swapChain.swapChain, 0, cb);
});
await withVoidCallback((cb) {
Renderer_renderRenderThread(
@@ -607,9 +640,14 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
await withVoidCallback((cb) {
Renderer_endFrameRenderThread(renderer, cb);
});
await withVoidCallback((cb) {
Engine_flushAndWaitRenderThead(engine, cb);
Engine_destroyFenceRenderThread(engine, fence, cb);
});
// await withVoidCallback((cb) {
// Engine_flushAndWaitRenderThead(engine, cb);
// });
return out;
}
@@ -623,7 +661,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
///
///
///
Future<ThermionAsset> loadGlbFromBuffer(
Future<ThermionAsset> loadGltfFromBuffer(
Uint8List data, Pointer animationManager,
{int numInstances = 1,
bool keepData = false,
@@ -631,7 +669,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
int layer = 0,
String? relativeResourcePath,
bool loadResourcesAsync = false}) async {
if (relativeResourcePath != null && !relativeResourcePath!.endsWith("/")) {
if (relativeResourcePath != null && !relativeResourcePath.endsWith("/")) {
relativeResourcePath = "$relativeResourcePath/";
}
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
@@ -648,7 +686,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
var resourceUris = SceneAsset_getResourceUris(asset);
var resourceUriCount = SceneAsset_getResourceUriCount(asset);
final resources = <FinalizableUint8List>[];
for (int i = 0; i < resourceUriCount; i++) {

View File

@@ -202,7 +202,7 @@ class FFIMaterialInstance extends MaterialInstance {
completer.complete();
};
final nativeCallable = NativeCallable<Void Function()>.listener(func);
RenderLoop_addTask(nativeCallable.nativeFunction);
RenderThread_addTask(nativeCallable.nativeFunction);
await completer.future;
}
}

View File

@@ -11,6 +11,9 @@ class FFIView extends View {
final Pointer<TView> view;
final FFIFilamentApp app;
bool _renderable = false;
bool get renderable => _renderable;
FFIRenderTarget? renderTarget;
FFIView(this.view, this.app) {
@@ -20,8 +23,19 @@ class FFIView extends View {
}
}
Future setRenderable(bool renderable) async {
this._renderable = renderable;
}
@override
Future setViewport(int width, int height) async {
// var width_logbase2 = log(width) / ln2;
// var height_logbase2 = log(height) / ln2;
// var newWidth = pow(2.0, width_logbase2.ceil());
// var newHeight = pow(2.0, height_logbase2.ceil());
// print("old: ${width}x${height} new: ${height}x${newHeight}");
// width = newWidth.toInt();
// height = newHeight.toInt();
View_setViewport(view, width, height);
}
@@ -80,8 +94,7 @@ class FFIView extends View {
@override
Future setToneMapper(ToneMapper mapper) async {
await withVoidCallback((cb) =>
View_setToneMappingRenderThread(
await withVoidCallback((cb) => View_setToneMappingRenderThread(
view, app.engine, TToneMapping.values[mapper.index], cb));
}

View File

@@ -473,6 +473,22 @@ external TViewport View_getViewport(
ffi.Pointer<TView> view,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.UnsignedInt)>(
symbol: "View_setBlendMode", isLeaf: true)
external void _View_setBlendMode(
ffi.Pointer<TView> view,
int blendMode,
);
void View_setBlendMode(
ffi.Pointer<TView> view,
TBlendMode blendMode,
) =>
_View_setBlendMode(
view,
blendMode.value,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
isLeaf: true)
external void View_setViewport(
@@ -1494,18 +1510,30 @@ external void RenderTicker_setRenderable(
);
@ffi.Native<ffi.Void Function()>(isLeaf: true)
external void RenderLoop_create();
external void RenderThread_create();
@ffi.Native<ffi.Void Function()>(isLeaf: true)
external void RenderLoop_destroy();
external void RenderThread_destroy();
@ffi.Native<
ffi.Void Function(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void RenderLoop_requestAnimationFrame(
external void RenderThread_requestAnimationFrame(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderTicker>)>(isLeaf: true)
external void RenderThread_setRenderTicker(
ffi.Pointer<TRenderTicker> tRenderTicker,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void RenderThread_addTask(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> task,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TRenderTicker>, ffi.Uint64,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
@@ -1515,13 +1543,6 @@ external void RenderTicker_renderRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void RenderLoop_addTask(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> task,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
@@ -3212,6 +3233,13 @@ external ffi.Pointer<TAnimationManager> AnimationManager_create(
ffi.Pointer<TScene> tScene,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, ffi.Uint64)>(
isLeaf: true)
external void AnimationManager_update(
ffi.Pointer<TAnimationManager> tAnimationManager,
int frameTimeInNanos,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, EntityId)>(
isLeaf: true)
external void AnimationManager_addAnimationComponent(
@@ -3951,6 +3979,20 @@ enum TQualityLevel {
};
}
enum TBlendMode {
OPAQUE(0),
TRANSLUCENT(1);
final int value;
const TBlendMode(this.value);
static TBlendMode fromValue(int value) => switch (value) {
0 => OPAQUE,
1 => TRANSLUCENT,
_ => throw ArgumentError("Unknown value for TBlendMode: $value"),
};
}
typedef PickCallback = ffi.Pointer<ffi.NativeFunction<PickCallbackFunction>>;
typedef PickCallbackFunction = ffi.Void Function(
ffi.Uint32 requestId,

View File

@@ -33,8 +33,6 @@ class ThermionViewerFFI extends ThermionViewer {
late final FFIFilamentApp app;
final FFIRenderTarget? renderTarget;
late final FFIView view;
late final FFIScene scene;
late final Pointer<TAnimationManager> animationManager;
@@ -43,7 +41,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
///
ThermionViewerFFI({required this.loadAssetFromUri, this.renderTarget}) {
ThermionViewerFFI({required this.loadAssetFromUri}) {
if (FilamentApp.instance == null) {
throw Exception("FilamentApp has not been created");
}
@@ -56,7 +54,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
///
Future setViewport(double width, double height) async {
Future setViewport(int width, int height) async {
await view.setViewport(width.toInt(), height.toInt());
for (final camera in _cameras) {
@@ -69,12 +67,12 @@ class ThermionViewerFFI extends ThermionViewer {
far = kFar;
}
var aspect = width / height;
var aspect = width.toDouble() / height.toDouble();
var focalLength = await camera.getFocalLength();
if (focalLength.abs() < 0.1) {
focalLength = kFocalLength;
}
camera.setLensProjection(
await camera.setLensProjection(
near: near, far: far, aspect: aspect, focalLength: focalLength);
}
}
@@ -85,6 +83,14 @@ class ThermionViewerFFI extends ThermionViewer {
await withPointerCallback<TView>(
(cb) => Engine_createViewRenderThread(app.engine, cb)),
app);
await view.setFrustumCullingEnabled(true);
View_setBlendMode(view.view, TBlendMode.TRANSLUCENT);
View_setShadowsEnabled(view.view, false);
View_setStencilBufferEnabled(view.view, false);
View_setAntiAliasing(view.view, false, false, false);
View_setDitheringEnabled(view.view, false);
View_setRenderQuality(view.view, TQualityLevel.MEDIUM);
await FilamentApp.instance!.setClearColor(1.0, 0.0, 0.0, 1.0);
scene = FFIScene(Engine_createScene(app.engine));
await view.setScene(scene);
final camera = FFICamera(
@@ -92,12 +98,10 @@ class ThermionViewerFFI extends ThermionViewer {
(cb) => Engine_createCameraRenderThread(app.engine, cb)),
app);
_cameras.add(camera);
await camera.setLensProjection();
await view.setCamera(camera);
if (renderTarget != null) {
await view.setRenderTarget(renderTarget);
}
animationManager = await withPointerCallback<TAnimationManager>((cb) =>
AnimationManager_createRenderThread(app.engine, scene.scene, cb));
@@ -180,9 +184,13 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
@override
Future clearBackgroundImage() async {
await _backgroundImage?.destroy();
_backgroundImage = null;
Future clearBackgroundImage({bool destroy = false}) async {
if (destroy) {
await _backgroundImage?.destroy();
_backgroundImage = null;
} else {
_backgroundImage?.hideImage();
}
}
///
@@ -335,7 +343,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future destroyLights() async {
for (final light in _lights) {
for (final light in _lights.toList()) {
await removeLight(light);
}
}
@@ -347,37 +355,45 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
@override
Future<ThermionAsset> loadGlb(String path,
{int numInstances = 1, bool keepData = false, String? relativeResourcePath}) async {
Future<ThermionAsset> loadGltf(String path,
{bool addToScene = true,
int numInstances = 1,
bool keepData = false,
String? relativeResourcePath}) async {
final data = await loadAssetFromUri(path);
return loadGlbFromBuffer(data,
numInstances: numInstances, keepData: keepData, relativeResourcePath: relativeResourcePath);
return loadGltfFromBuffer(data,
addToScene: addToScene,
numInstances: numInstances,
keepData: keepData,
relativeResourcePath: relativeResourcePath);
}
///
///
///
@override
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data,
{int numInstances = 1,
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data,
{bool addToScene = true,
int numInstances = 1,
bool keepData = false,
int priority = 4,
int layer = 0,
bool loadResourcesAsync = false,
String? relativeResourcePath}) async {
var asset = await FilamentApp.instance!.loadGlbFromBuffer(data, animationManager,
var asset = await FilamentApp.instance!.loadGltfFromBuffer(
data, animationManager,
numInstances: numInstances,
keepData: keepData,
priority: priority,
layer: layer,
loadResourcesAsync: loadResourcesAsync,
relativeResourcePath:relativeResourcePath
) as FFIAsset;
_assets.add(asset);
relativeResourcePath: relativeResourcePath) as FFIAsset;
await scene.add(asset);
_assets.add(asset);
if (addToScene) {
await scene.add(asset);
}
return asset;
}
@@ -424,6 +440,8 @@ class ThermionViewerFFI extends ThermionViewer {
@override
Future setPostProcessing(bool enabled) async {
View_setPostProcessing(view.view, enabled);
await withVoidCallback(
(cb) => Engine_flushAndWaitRenderThead(app.engine, cb));
}
///
@@ -655,7 +673,8 @@ class ThermionViewerFFI extends ThermionViewer {
@override
Future<ThermionAsset> createGeometry(Geometry geometry,
{List<MaterialInstance>? materialInstances,
bool keepData = false}) async {
bool keepData = false,
bool addToScene = true}) async {
var assetPtr = await withPointerCallback<TSceneAsset>((callback) {
var ptrList = Int64List(materialInstances?.length ?? 0);
if (materialInstances != null && materialInstances.isNotEmpty) {
@@ -688,7 +707,9 @@ class ThermionViewerFFI extends ThermionViewer {
}
var asset = FFIAsset(assetPtr, app, animationManager);
if (addToScene) {
await scene.add(asset);
}
return asset;
}

View File

@@ -71,7 +71,7 @@ abstract class ThermionViewer {
///
/// Removes the background image.
///
Future clearBackgroundImage();
Future clearBackgroundImage({bool destroy = false});
///
/// Sets the color for the background plane (positioned at the maximum depth, i.e. behind all other objects including the skybox).
@@ -128,10 +128,11 @@ abstract class ThermionViewer {
/// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData].
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
///
Future<ThermionAsset> loadGlb(String path,
{int numInstances = 1,
Future<ThermionAsset> loadGltf(String path,
{ bool addToScene=true,
int numInstances = 1,
bool keepData = false,
String relativeResourcePath});
String? relativeResourcePath});
///
/// Load the .glb asset from the specified buffer, adding all entities to the scene.
@@ -142,7 +143,7 @@ abstract class ThermionViewer {
/// be loaded asynchronously (so expect some material/texture pop-in);
///
///
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data,
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data,
{int numInstances = 1,
bool keepData = false,
int priority = 4,
@@ -177,6 +178,11 @@ abstract class ThermionViewer {
///
Future setViewFrustumCulling(bool enabled);
///
/// Sets the viewport sizes and updates all cameras to use the new aspect ratio.
///
Future setViewport(int width, int height);
///
/// Set the world space position for [lightEntity] to the given coordinates.
///
@@ -230,7 +236,7 @@ abstract class ThermionViewer {
///
///
Future<ThermionAsset> createGeometry(Geometry geometry,
{List<MaterialInstance>? materialInstances, bool keepData = false});
{List<MaterialInstance>? materialInstances, bool keepData = false, bool addToScene=true});
///
/// The gizmo for translating/rotating objects. Only one gizmo can be active for a given view.

View File

@@ -9,6 +9,12 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future addToScene(covariant ThermionAsset asset) {
// TODO: implement addToScene
throw UnimplementedError();
}
@override
Future clearBackgroundImage() {
// TODO: implement clearBackgroundImage
@@ -21,12 +27,6 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future<ThermionAsset> createGeometry(Geometry geometry, {List<MaterialInstance>? materialInstances, bool keepData = false}) {
// TODO: implement createGeometry
throw UnimplementedError();
}
@override
Future<GizmoAsset> createGizmo(covariant View view, GizmoType type) {
// TODO: implement createGizmo
@@ -92,23 +92,17 @@ class ThermionViewerStub extends ThermionViewer {
Future<bool> get initialized => throw UnimplementedError();
@override
Future<ThermionAsset> loadGlb(String path, {int numInstances = 1, bool keepData = false}) {
// TODO: implement loadGlb
throw UnimplementedError();
}
@override
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false}) {
// TODO: implement loadGlbFromBuffer
throw UnimplementedError();
}
@override
Future<ThermionAsset> loadGltf(String path, String relativeResourcePath, {bool keepData = false}) {
Future<ThermionAsset> loadGltf(String path, {int numInstances = 1, bool keepData = false, String? relativeResourcePath}) {
// TODO: implement loadGltf
throw UnimplementedError();
}
@override
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false, String? relativeResourcePath}) {
// TODO: implement loadGltfFromBuffer
throw UnimplementedError();
}
@override
Future loadIbl(String lightingPath, {double intensity = 30000}) {
// TODO: implement loadIbl
@@ -136,6 +130,12 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future removeFromScene(covariant ThermionAsset asset) {
// TODO: implement removeFromScene
throw UnimplementedError();
}
@override
Future removeGridOverlay() {
// TODO: implement removeGridOverlay
@@ -287,5 +287,5 @@ class ThermionViewerStub extends ThermionViewer {
@override
// TODO: implement view
View get view => throw UnimplementedError();
}