refactoring
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user