refactoring

This commit is contained in:
Nick Fisher
2025-03-18 16:26:47 +08:00
parent 07b80071a4
commit 77fe40848b
41 changed files with 1900 additions and 2342 deletions

View File

@@ -1,5 +1,7 @@
import 'dart:ffi';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/layers.dart';
import 'package:vector_math/vector_math_64.dart';
import '../../../../utils/src/matrix.dart';
@@ -8,11 +10,10 @@ import 'thermion_dart.g.dart' as g;
class FFICamera extends Camera {
final Pointer<g.TCamera> camera;
final Pointer<g.TEngine> engine;
final Pointer<g.TTransformManager> transformManager;
final FFIFilamentApp app;
late ThermionEntity _entity;
FFICamera(this.camera, this.engine, this.transformManager) {
FFICamera(this.camera, this.app) {
_entity = g.Camera_getEntity(camera);
}
@@ -30,7 +31,8 @@ class FFICamera extends Camera {
@override
Future setTransform(Matrix4 transform) async {
var entity = g.Camera_getEntity(camera);
g.TransformManager_setTransform(transformManager, entity, matrix4ToDouble4x4(transform));
g.TransformManager_setTransform(
app.transformManager, entity, matrix4ToDouble4x4(transform));
}
@override
@@ -84,9 +86,8 @@ class FFICamera extends Camera {
@override
Future setProjection(Projection projection, double left, double right,
double bottom, double top, double near, double far) async {
double bottom, double top, double near, double far) async {
var pType = g.Projection.values[projection.index];
g.Camera_setProjection(camera, pType, left,
right, bottom, top, near, far);
g.Camera_setProjection(camera, pType, left, right, bottom, top, near, far);
}
}

View File

@@ -0,0 +1,150 @@
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
import 'package:thermion_dart/src/viewer/src/filament/filament.dart';
import 'package:thermion_dart/thermion_dart.dart';
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
FFIFilamentConfig(
{required super.backend,
required super.resourceLoader,
required super.uberArchivePath});
}
class FFIFilamentApp extends FilamentApp<Pointer> {
static FFIFilamentApp? _instance;
final Pointer<TEngine> engine;
final Pointer<TGltfAssetLoader> gltfAssetLoader;
final Pointer<TGltfResourceLoader> gltfResourceLoader;
final Pointer<TRenderer> renderer;
final Pointer<TTransformManager> transformManager;
final Pointer<TLightManager> lightManager;
final Pointer<TRenderableManager> renderableManager;
final Pointer<TMaterialProvider> ubershaderMaterialProvider;
final Pointer<TRenderTicker> renderTicker;
FFIFilamentApp(
this.engine,
this.gltfAssetLoader,
this.gltfResourceLoader,
this.renderer,
this.transformManager,
this.lightManager,
this.renderableManager,
this.ubershaderMaterialProvider,
this.renderTicker)
: super(
engine: engine,
gltfAssetLoader: gltfAssetLoader,
gltfResourceLoader: gltfResourceLoader,
renderer: renderer,
transformManager: transformManager,
lightManager: lightManager,
renderableManager: renderableManager,
ubershaderMaterialProvider: ubershaderMaterialProvider);
Future<FFIFilamentApp> create(FFIFilamentConfig config) async {
if (_instance == null) {
RenderLoop_destroy();
RenderLoop_create();
final engine = await withPointerCallback<TEngine>((cb) =>
Engine_createRenderThread(
TBackend.values[config.backend.index].index,
config.platform ?? nullptr,
config.sharedContext ?? nullptr,
config.stereoscopicEyeCount,
config.disableHandleUseAfterFreeCheck,
cb));
final gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
(cb) => GltfResourceLoader_createRenderThread(engine, cb));
final gltfAssetLoader = await withPointerCallback<TGltfAssetLoader>(
(cb) => GltfAssetLoader_createRenderThread(engine, nullptr, cb));
final renderer = await withPointerCallback<TRenderer>(
(cb) => Engine_createRendererRenderThread(engine, cb));
final ubershaderMaterialProvider =
await withPointerCallback<TMaterialProvider>(
(cb) => GltfAssetLoader_getMaterialProvider(gltfAssetLoader));
final transformManager = Engine_getTransformManager(engine);
final lightManager = Engine_getLightManager(engine);
final renderableManager = Engine_getRenderableManager(engine);
final renderTicker = await withPointerCallback<TRenderTicker>(
(cb) => RenderTicker_create());
_instance = FFIFilamentApp(
engine,
gltfAssetLoader,
gltfResourceLoader,
renderer,
transformManager,
lightManager,
renderableManager,
ubershaderMaterialProvider);
}
return _instance!;
}
@override
Future<SwapChain> createHeadlessSwapChain(int width, int height,
{bool hasStencilBuffer = false}) async {
var flags = TSWAP_CHAIN_CONFIG_TRANSPARENT | TSWAP_CHAIN_CONFIG_READABLE;
if (hasStencilBuffer) {
flags |= TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
}
final swapChain = await withPointerCallback<TSwapChain>((cb) =>
Engine_createHeadlessSwapChainRenderThread(
this.engine, width, height, flags, cb));
return FFISwapChain(swapChain);
}
///
///
///
@override
Future<SwapChain> createSwapChain(Pointer window,
{bool hasStencilBuffer = false}) async {
var flags = TSWAP_CHAIN_CONFIG_TRANSPARENT | TSWAP_CHAIN_CONFIG_READABLE;
if (hasStencilBuffer) {
flags |= TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
}
final swapChain = await withPointerCallback<TSwapChain>((cb) =>
Engine_createSwapChainRenderThread(
this.engine, window.cast<Void>(), flags, cb));
return FFISwapChain(swapChain);
}
///
///
///
Future destroySwapChain(SwapChain swapChain) async {
await withVoidCallback((callback) {
Engine_destroySwapChainRenderThread(
engine, (swapChain as FFISwapChain).swapChain, callback);
});
}
@override
Future destroy() {
throw UnimplementedError();
}
///
///
///
Future<RenderTarget> createRenderTarget(int width, int height,
{covariant FFITexture? color, covariant FFITexture? depth}) async {
final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
RenderTarget_createRenderThread(engine, width, height,
color?.pointer ?? nullptr, depth?.pointer ?? nullptr, cb);
});
return FFIRenderTarget(renderTarget, this);
}
}

View File

@@ -1,25 +1,30 @@
import 'dart:ffi';
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
import 'package:thermion_dart/thermion_dart.dart';
class FFIRenderTarget extends RenderTarget {
final Pointer<TRenderTarget> renderTarget;
final Pointer<TViewer> viewer;
final Pointer<TEngine> engine;
final FFIFilamentApp app;
FFIRenderTarget(this.renderTarget, this.viewer, this.engine);
FFIRenderTarget(this.renderTarget, this.app);
@override
Future<Texture> getColorTexture() async {
final ptr = RenderTarget_getColorTexture(renderTarget);
return FFITexture(engine, ptr);
return FFITexture(app.engine, ptr);
}
@override
Future<Texture> getDepthTexture() async {
final ptr = RenderTarget_getDepthTexture(renderTarget);
return FFITexture(engine, ptr);
return FFITexture(app.engine, ptr);
}
@override
Future destroy() async {
await withVoidCallback((cb) => RenderTarget_destroy(app.engine, renderTarget));
}
}

View File

@@ -0,0 +1,19 @@
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/scene.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
import 'callbacks.dart';
import 'ffi_camera.dart';
class FFIScene extends Scene {
final Pointer<TScene> scene;
final FFIFilamentApp app;
FFIRenderTarget? renderTarget;
FFIScene(this.scene, this.app) {
}
}

View File

@@ -5,7 +5,6 @@ import 'package:thermion_dart/thermion_dart.dart';
class FFISwapChain extends SwapChain {
final Pointer<TSwapChain> swapChain;
final Pointer<TViewer> viewer;
FFISwapChain(this.swapChain, this.viewer);
FFISwapChain(this.swapChain);
}

View File

@@ -1,26 +1,22 @@
import 'dart:ffi';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/scene.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
import 'callbacks.dart';
import 'ffi_camera.dart';
import 'thermion_viewer_ffi.dart';
class FFIView extends View {
final Pointer<TView> view;
final Pointer<TViewer> viewer;
final Pointer<TEngine> engine;
final FFIFilamentApp app;
FFIRenderTarget? renderTarget;
FFIView(this.view, this.viewer, this.engine) {
FFIView(this.view, this.app) {
final renderTargetPtr = View_getRenderTarget(view);
if (renderTargetPtr != nullptr) {
renderTarget = FFIRenderTarget(
renderTargetPtr,
viewer,
engine
);
renderTarget = FFIRenderTarget(renderTargetPtr, app);
}
}
@@ -56,10 +52,9 @@ class FFIView extends View {
@override
Future<Camera> getCamera() async {
final engine = Viewer_getEngine(viewer);
final transformManager = Engine_getTransformManager(engine);
final transformManager = Engine_getTransformManager(app.engine);
final cameraPtr = View_getCamera(view);
return FFICamera(cameraPtr, engine, transformManager);
return FFICamera(cameraPtr, app.engine, transformManager);
}
@override
@@ -73,7 +68,7 @@ class FFIView extends View {
}
Future setRenderable(bool renderable, FFISwapChain swapChain) async {
Viewer_setViewRenderable(viewer, swapChain.swapChain, view, renderable);
throw UnimplementedError();
}
@override
@@ -90,8 +85,7 @@ class FFIView extends View {
@override
Future setToneMapper(ToneMapper mapper) async {
final engine = await Viewer_getEngine(viewer);
View_setToneMappingRenderThread(view, engine, mapper.index);
View_setToneMappingRenderThread(view, app.engine, mapper.index);
}
Future setStencilBufferEnabled(bool enabled) async {
@@ -114,4 +108,8 @@ class FFIView extends View {
Future setRenderQuality(QualityLevel quality) async {
View_setRenderQuality(view, TQualityLevel.values[quality.index]);
}
Future setScene(covariant FFIScene scene) async {
await withVoidCallback((cb) => View_setScene(view, scene.scene));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,11 +4,16 @@ import 'dart:math';
import 'dart:typed_data';
import 'package:animation_tools_dart/animation_tools_dart.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_gizmo.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
import 'package:thermion_dart/src/viewer/src/filament/filament.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/config.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/layers.dart';
import 'package:vector_math/vector_math_64.dart';
import 'package:vector_math/vector_math_64.dart' as v64;
import '../../../../utils/src/matrix.dart';
@@ -19,84 +24,24 @@ import 'callbacks.dart';
import 'ffi_camera.dart';
import 'ffi_view.dart';
class FFIBindings {
final Pointer<TSceneManager> sceneManager;
final Pointer<TEngine> engine;
final Pointer<TMaterialProvider> unlitMaterialProvider;
final Pointer<TMaterialProvider> ubershaderMaterialProvider;
final Pointer<TTransformManager> transformManager;
final Pointer<TLightManager> lightManager;
final Pointer<TRenderableManager> renderableManager;
final Pointer<TViewer> viewer;
final Pointer<TAnimationManager> animationManager;
final Pointer<TNameComponentManager> nameComponentManager;
final Pointer<TRenderer> renderer;
FFIBindings(
{required this.renderer,
required this.sceneManager,
required this.engine,
required this.unlitMaterialProvider,
required this.ubershaderMaterialProvider,
required this.transformManager,
required this.lightManager,
required this.renderableManager,
required this.viewer,
required this.animationManager,
required this.nameComponentManager});
}
// ignore: constant_identifier_names
const ThermionEntity FILAMENT_ASSET_ERROR = 0;
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
///
///
///
class ThermionViewerFFI extends ThermionViewer {
final _logger = Logger("ThermionViewerFFI");
Pointer<TSceneManager>? _sceneManager;
Pointer<TEngine>? _engine;
Pointer<TMaterialProvider>? _unlitMaterialProvider;
Pointer<TMaterialProvider>? _ubershaderMaterialProvider;
Pointer<TTransformManager>? _transformManager;
Pointer<TLightManager>? _lightManager;
Pointer<TRenderableManager>? _renderableManager;
Pointer<TViewer>? _viewer;
Pointer<TAnimationManager>? _animationManager;
Pointer<TNameComponentManager>? _nameComponentManager;
late FFIBindings bindings;
final String? uberArchivePath;
final _initialized = Completer<bool>();
Future<bool> get initialized => _initialized.future;
final Pointer<Void> resourceLoader;
var _driver = nullptr.cast<Void>();
late final RenderCallback _renderCallback;
var _renderCallbackOwner = nullptr.cast<Void>();
var _sharedContext = nullptr.cast<Void>();
late NativeCallable<PickCallbackFunction> _onPickResultCallable;
///
///
///
ThermionViewerFFI(
{RenderCallback? renderCallback,
Pointer<Void>? renderCallbackOwner,
required this.resourceLoader,
Pointer<Void>? driver,
Pointer<Void>? sharedContext,
this.uberArchivePath}) {
this._renderCallbackOwner = renderCallbackOwner ?? nullptr;
this._renderCallback = renderCallback ?? nullptr;
this._driver = driver ?? nullptr;
this._sharedContext = sharedContext ?? nullptr;
late final FFIFilamentApp app;
late final FFIRenderTarget? renderTarget;
///
///
///
ThermionViewerFFI(this.app, {this.renderTarget}) {
_onPickResultCallable =
NativeCallable<PickCallbackFunction>.listener(_onPickResult);
@@ -107,49 +52,21 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
Future<RenderTarget> createRenderTarget(int width, int height,
{int? colorTextureHandle, int? depthTextureHandle}) async {
{covariant FFITexture? color, covariant FFITexture? depth}) async {
final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
Viewer_createRenderTargetRenderThread(_viewer!, colorTextureHandle ?? 0,
depthTextureHandle ?? 0, width, height, cb);
RenderTarget_createRenderThread(app.engine, width, height,
color?.pointer ?? nullptr, depth?.pointer ?? nullptr, cb);
});
return FFIRenderTarget(renderTarget, _viewer!, _engine!);
}
///
///
///
@override
Future destroyRenderTarget(FFIRenderTarget renderTarget) async {
if (_disposing || _viewer == null) {
_logger.info(
"Viewer is being (or has been) disposed; this will clean up all render targets.");
} else {
await withVoidCallback((cb) {
Viewer_destroyRenderTargetRenderThread(
_viewer!, renderTarget.renderTarget, cb);
});
}
}
///
///
///
Future<View> createView() async {
var view = await withPointerCallback<TView>((cb) {
Viewer_createViewRenderThread(_viewer!, cb);
});
if (view == nullptr) {
throw Exception("Failed to create view");
}
return FFIView(view, _viewer!, _engine!);
return FFIRenderTarget(renderTarget, app);
}
///
///
///
Future setViewportAndCameraProjection(double width, double height) async {
var mainView = FFIView(Viewer_getViewAt(_viewer!, 0), _viewer!, _engine!);
var mainView =
FFIView(Viewer_getViewAt(_viewer!, 0), _viewer!, app.engine!);
mainView.setViewport(width.toInt(), height.toInt());
final cameraCount = await getCameraCount();
@@ -175,86 +92,25 @@ class ThermionViewerFFI extends ThermionViewer {
}
}
///
///
///
Future<SwapChain> createHeadlessSwapChain(int width, int height) async {
var swapChain = await withPointerCallback<TSwapChain>((callback) {
return Viewer_createHeadlessSwapChainRenderThread(
_viewer!, width, height, callback);
});
return FFISwapChain(swapChain, _viewer!);
}
///
///
///
Future<SwapChain> createSwapChain(int surface) async {
var swapChain = await withPointerCallback<TSwapChain>((callback) {
return Viewer_createSwapChainRenderThread(
_viewer!, Pointer<Void>.fromAddress(surface), callback);
});
return FFISwapChain(swapChain, _viewer!);
}
///
///
///
Future destroySwapChain(SwapChain swapChain) async {
if (_viewer != null) {
await withVoidCallback((callback) {
Viewer_destroySwapChainRenderThread(
_viewer!, (swapChain as FFISwapChain).swapChain, callback);
});
}
}
late final FFIView view;
late final FFIScene scene;
late final FFICamera camera;
Future _initialize() async {
_logger.info("Initializing ThermionViewerFFI");
Viewer_destroyOnRenderThread(nullptr);
RenderLoop_destroy();
RenderLoop_create();
final uberarchivePtr =
uberArchivePath?.toNativeUtf8(allocator: allocator).cast<Char>() ??
nullptr;
_viewer = await withPointerCallback(
(Pointer<NativeFunction<Void Function(Pointer<TViewer>)>> callback) {
Viewer_createOnRenderThread(_sharedContext, _driver, uberarchivePtr,
resourceLoader, _renderCallback, _renderCallbackOwner, callback);
});
allocator.free(uberarchivePtr);
if (_viewer!.address == 0) {
throw Exception("Failed to create viewer. Check logs for details");
view = FFIView(
await withPointerCallback<TView>(
(cb) => Engine_createViewRenderThread(app.engine, cb)),
app);
scene = FFIScene(Engine_createScene(app.engine), app);
await view.setScene(scene);
camera = FFICamera(
await withPointerCallback<TCamera>(
(cb) => Engine_createCameraRenderThread(app.engine, cb)),
app);
if (renderTarget != null) {
await view.setRenderTarget(renderTarget);
}
_sceneManager = Viewer_getSceneManager(_viewer!);
_unlitMaterialProvider =
SceneManager_getUnlitMaterialProvider(_sceneManager!);
_ubershaderMaterialProvider =
SceneManager_getUbershaderMaterialProvider(_sceneManager!);
_engine = Viewer_getEngine(_viewer!);
_transformManager = Engine_getTransformManager(_engine!);
_lightManager = Engine_getLightManager(_engine!);
_animationManager = SceneManager_getAnimationManager(_sceneManager!);
_nameComponentManager =
SceneManager_getNameComponentManager(_sceneManager!);
_renderableManager = Engine_getRenderableManager(_engine!);
bindings = FFIBindings(
sceneManager: _sceneManager!,
engine: _engine!,
unlitMaterialProvider: _unlitMaterialProvider!,
ubershaderMaterialProvider: _ubershaderMaterialProvider!,
transformManager: _transformManager!,
lightManager: _lightManager!,
renderableManager: _renderableManager!,
viewer: _viewer!,
animationManager: _animationManager!,
nameComponentManager: _nameComponentManager!,
renderer: Viewer_getRenderer(_viewer!));
this._initialized.complete(true);
}
@@ -272,32 +128,24 @@ class ThermionViewerFFI extends ThermionViewer {
@override
Future setRendering(bool render) async {
_rendering = render;
// await withVoidCallback((cb) {
// set_rendering_render_thread(_viewer!, render, cb);
// });
}
///
///
///
@override
Future render({FFISwapChain? swapChain}) async {
final view = (await getViewAt(0)) as FFIView;
swapChain ??= FFISwapChain(Viewer_getSwapChainAt(_viewer!, 0), _viewer!);
Viewer_renderRenderThread(_viewer!, view.view, swapChain.swapChain);
Future render() async {
RenderTicker_renderRenderThread(app.renderTicker, 0);
// Viewer_renderRenderThread(_viewer!, view.view, swapChain.swapChain);
}
///
///
///
@override
Future<List<Uint8List>> capture(
List<({View view, SwapChain? swapChain, RenderTarget? renderTarget})>
targets) async {
var renderer = Viewer_getRenderer(_viewer!);
Future<Uint8List> capture() async {
final fence = await withPointerCallback<TFence>((cb) {
Engine_createFenceRenderThread(_engine!, cb);
Engine_createFenceRenderThread(app.engine!, cb);
});
var pixelBuffers = <Uint8List>[];
@@ -337,11 +185,11 @@ class ThermionViewerFFI extends ThermionViewer {
});
await withVoidCallback((cb) {
Engine_flushAndWaitRenderThead(_engine!, cb);
Engine_flushAndWaitRenderThead(app.engine!, cb);
});
await withVoidCallback((cb) {
Engine_destroyFenceRenderThread(_engine!, fence, cb);
Engine_destroyFenceRenderThread(app.engine!, fence, cb);
});
// await withVoidCallback((cb) {
@@ -400,9 +248,6 @@ class ThermionViewerFFI extends ThermionViewer {
await mInstance.dispose();
}
await destroyLights();
Viewer_destroyOnRenderThread(_viewer!);
RenderLoop_destroy();
_sceneManager = null;
_viewer = null;
@@ -410,7 +255,7 @@ class ThermionViewerFFI extends ThermionViewer {
for (final callback in _onDispose) {
await callback.call();
}
await app.destroy();
_onDispose.clear();
_disposing = false;
}
@@ -635,7 +480,7 @@ class ThermionViewerFFI extends ThermionViewer {
}
var thermionAsset = FFIAsset(
asset, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
asset, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
return thermionAsset;
}
@@ -675,7 +520,7 @@ class ThermionViewerFFI extends ThermionViewer {
throw Exception("An error occurred loading GLB from buffer");
}
return FFIAsset(
assetPtr, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
assetPtr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
}
///
@@ -697,7 +542,7 @@ class ThermionViewerFFI extends ThermionViewer {
}
return FFIAsset(
assetPtr, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
assetPtr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
}
///
@@ -1780,7 +1625,7 @@ class ThermionViewerFFI extends ThermionViewer {
}
var asset = FFIAsset(
assetPtr, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
assetPtr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
return asset;
}
@@ -1841,7 +1686,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future setPriority(ThermionEntity entityId, int priority) async {
RenderableManager_setPriority(_renderableManager!, entityId, priority);
RenderableManager_setPriority(app.renderableManager, entityId, priority);
}
///
@@ -1899,7 +1744,7 @@ class ThermionViewerFFI extends ThermionViewer {
}
});
_grid = FFIAsset(
ptr, _sceneManager!, _engine!, _unlitMaterialProvider!, this);
ptr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
}
await _grid!.addToScene();
await setLayerVisibility(VisibilityLayers.OVERLAY, true);
@@ -1929,7 +1774,7 @@ class ThermionViewerFFI extends ThermionViewer {
var bitmask = flags.fold(0, (a, b) => a | b.index);
final texturePtr = await withPointerCallback<TTexture>((cb) {
Texture_buildRenderThread(
_engine!,
app.engine!,
width,
height,
depth,
@@ -1944,7 +1789,7 @@ class ThermionViewerFFI extends ThermionViewer {
throw Exception("Failed to create texture");
}
return FFITexture(
_engine!,
app.engine!,
texturePtr,
);
}
@@ -1958,7 +1803,6 @@ class ThermionViewerFFI extends ThermionViewer {
double anisotropy = 0.0,
TextureCompareMode compareMode = TextureCompareMode.NONE,
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
return FFITextureSampler(TextureSampler_create());
final samplerPtr = TextureSampler_create();
TextureSampler_setMinFilter(
samplerPtr, TSamplerMinFilter.values[minFilter.index]);
@@ -2011,9 +1855,10 @@ class ThermionViewerFFI extends ThermionViewer {
///
Future<Material> createMaterial(Uint8List data) async {
var ptr = await withPointerCallback<TMaterial>((cb) {
Engine_buildMaterialRenderThread(_engine!, data.address, data.length, cb);
Engine_buildMaterialRenderThread(
app.engine!, data.address, data.length, cb);
});
return FFIMaterial(ptr, _engine!, _sceneManager!);
return FFIMaterial(ptr, app.engine!, _sceneManager!);
}
///
@@ -2098,7 +1943,7 @@ class ThermionViewerFFI extends ThermionViewer {
final materialInstance = await withPointerCallback<TMaterialInstance>((cb) {
MaterialProvider_createMaterialInstanceRenderThread(
_ubershaderMaterialProvider!, key.address, cb);
app.ubershaderMaterialProvider, key.address, cb);
});
if (materialInstance == nullptr) {
throw Exception("Failed to create material instance");
@@ -2148,7 +1993,7 @@ class ThermionViewerFFI extends ThermionViewer {
Future<MaterialInstance> getMaterialInstanceAt(
ThermionEntity entity, int index) async {
final instancePtr = RenderableManager_getMaterialInstanceAt(
_renderableManager!, entity, index);
app.renderableManager, entity, index);
final instance = FFIMaterialInstance(instancePtr, _sceneManager!);
return instance;
@@ -2254,7 +2099,7 @@ class ThermionViewerFFI extends ThermionViewer {
if (view == nullptr) {
throw Exception("Failed to get view");
}
return FFIView(view, _viewer!, _engine!);
return FFIView(view, _viewer!, app.engine!);
}
@override
@@ -2278,7 +2123,7 @@ class ThermionViewerFFI extends ThermionViewer {
view,
gizmo.cast<TSceneAsset>(),
_sceneManager!,
_engine!,
app.engine!,
nullptr,
this,
gizmoEntities.toSet()
@@ -2289,14 +2134,15 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
Future setCastShadows(ThermionEntity entity, bool castShadows) async {
RenderableManager_setCastShadows(_renderableManager!, entity, castShadows);
RenderableManager_setCastShadows(
app.renderableManager, entity, castShadows);
}
///
///
///
Future<bool> isCastShadowsEnabled(ThermionEntity entity) async {
return RenderableManager_isShadowCaster(_renderableManager!, entity);
return RenderableManager_isShadowCaster(app.renderableManager, entity);
}
///
@@ -2304,14 +2150,14 @@ class ThermionViewerFFI extends ThermionViewer {
///
Future setReceiveShadows(ThermionEntity entity, bool receiveShadows) async {
RenderableManager_setReceiveShadows(
_renderableManager!, entity, receiveShadows);
app.renderableManager, entity, receiveShadows);
}
///
///
///
Future<bool> isReceiveShadowsEnabled(ThermionEntity entity) async {
return RenderableManager_isShadowReceiver(_renderableManager!, entity);
return RenderableManager_isShadowReceiver(app.renderableManager, entity);
}
///
@@ -2319,8 +2165,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
Future setClearOptions(
Vector4 clearColor, int clearStencil, bool clear, bool discard) async {
final renderer = Viewer_getRenderer(_viewer!);
Renderer_setClearOptions(renderer, clearColor.r, clearColor.g, clearColor.b,
clearColor.a, clearStencil, clear, discard);
Renderer_setClearOptions(app.renderer, clearColor.r, clearColor.g,
clearColor.b, clearColor.a, clearStencil, clear, discard);
}
}

View File

@@ -0,0 +1,78 @@
import 'package:thermion_dart/src/viewer/src/shared_types/engine.dart';
import 'package:thermion_dart/thermion_dart.dart';
class FilamentConfig<T, U> {
final Backend backend;
final T? renderCallback;
final U? renderCallbackOwner;
final U resourceLoader;
final U? platform;
final U? driver;
final U? sharedContext;
final String uberArchivePath;
final int stereoscopicEyeCount;
final bool disableHandleUseAfterFreeCheck;
FilamentConfig(
{required this.backend,
required this.resourceLoader,
required this.uberArchivePath,
this.renderCallback,
this.renderCallbackOwner,
this.platform,
this.driver,
this.sharedContext,
this.stereoscopicEyeCount = 1,
this.disableHandleUseAfterFreeCheck = false});
}
abstract class FilamentApp<T> {
final T engine;
final T gltfAssetLoader;
final T gltfResourceLoader;
final T renderer;
final T transformManager;
final T lightManager;
final T renderableManager;
final T ubershaderMaterialProvider;
FilamentApp(
{required this.engine,
required this.gltfAssetLoader,
required this.gltfResourceLoader,
required this.renderer,
required this.transformManager,
required this.lightManager,
required this.renderableManager,
required this.ubershaderMaterialProvider
});
///
///
///
Future<SwapChain> createHeadlessSwapChain(int width, int height,
{bool hasStencilBuffer = false});
///
///
///
Future<SwapChain> createSwapChain(T handle, {bool hasStencilBuffer = false});
///
///
///
Future destroySwapChain(SwapChain swapChain);
///
///
///
Future destroy();
///
///
///
Future<RenderTarget> createRenderTarget(
int width, int height, { covariant Texture? color, covariant Texture? depth });
}

View File

@@ -0,0 +1,28 @@
enum Backend {
/// !< Automatically selects an appropriate driver for the platform.
DEFAULT(0),
/// !< Selects the OpenGL/ES driver (default on Android)
OPENGL(1),
/// !< Selects the Vulkan driver if the platform supports it (default on Linux/Windows)
VULKAN(2),
/// !< Selects the Metal driver if the platform supports it (default on MacOS/iOS).
METAL(3),
/// !< Selects the no-op driver for testing purposes.
NOOP(4);
final int value;
const Backend(this.value);
static Backend fromValue(int value) => switch (value) {
0 => DEFAULT,
1 => OPENGL,
2 => VULKAN,
3 => METAL,
4 => NOOP,
_ => throw ArgumentError("Unknown value for TBackend: $value"),
};
}

View File

@@ -0,0 +1,3 @@
import 'package:thermion_dart/thermion_dart.dart';
final ThermionEntity FILAMENT_ENTITY_NULL = 0;

View File

@@ -0,0 +1,18 @@
const double kNear = 0.05;
const double kFar = 1000.0;
const double kFocalLength = 28.0;
enum VisibilityLayers {
DEFAULT_ASSET(0),
LAYER_1(1),
LAYER_2(2),
LAYER_3(3),
LAYER_4(4),
LAYER_5(5),
BACKGROUND(6),
OVERLAY(7);
final int value;
const VisibilityLayers(this.value);
}

View File

@@ -3,4 +3,5 @@ import 'package:thermion_dart/thermion_dart.dart';
abstract class RenderTarget {
Future<Texture> getColorTexture();
Future<Texture> getDepthTexture();
Future destroy();
}

View File

@@ -0,0 +1,4 @@
abstract class Scene {
}

View File

@@ -1,3 +1,5 @@
import 'package:thermion_dart/src/viewer/src/shared_types/layers.dart';
import '../../utils/src/gizmo.dart';
import 'shared_types/shared_types.dart';
export 'shared_types/shared_types.dart';
@@ -8,32 +10,12 @@ import 'package:vector_math/vector_math_64.dart';
import 'dart:async';
import 'package:animation_tools_dart/animation_tools_dart.dart';
const double kNear = 0.05;
const double kFar = 1000.0;
const double kFocalLength = 28.0;
enum VisibilityLayers {
DEFAULT_ASSET(0),
LAYER_1(1),
LAYER_2(2),
LAYER_3(3),
LAYER_4(4),
LAYER_5(5),
BACKGROUND(6),
OVERLAY(7);
final int value;
const VisibilityLayers(this.value);
}
final ThermionEntity FILAMENT_ENTITY_NULL = 0;
///
/// A high-level interface for interacting with a 3D scene.
/// This broadly maps to a single scene/view
///
abstract class ThermionViewer {
///
/// A Future that resolves when the underlying rendering context has been successfully created.
///
Future<bool> get initialized;
///
/// Whether the controller is currently rendering at [framerate].
///
@@ -47,7 +29,7 @@ abstract class ThermionViewer {
///
/// Render a single frame immediately.
///
Future render({covariant SwapChain? swapChain});
Future render();
///
/// Requests a single frame to be rendered. This is only intended to be used internally.
@@ -60,31 +42,6 @@ abstract class ThermionViewer {
Future<List<Uint8List>> capture(
covariant List<({View view, SwapChain? swapChain, RenderTarget? renderTarget})> targets);
///
///
///
Future<SwapChain> createHeadlessSwapChain(int width, int height);
///
///
///
Future<SwapChain> createSwapChain(int handle);
///
///
///
Future destroySwapChain(covariant SwapChain swapChain);
///
///
///
Future<RenderTarget> createRenderTarget(
int width, int height, { int? colorTextureHandle, int? depthTextureHandle });
///
///
///
Future destroyRenderTarget(covariant RenderTarget renderTarget);
///
///

View File

@@ -312,12 +312,6 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future setBloom(double bloom) {
// TODO: implement setBloom
throw UnimplementedError();
}
@override
Future setBoneTransform(
ThermionEntity entity, int boneIndex, Matrix4 transform,
@@ -768,12 +762,6 @@ class ThermionViewerStub extends ThermionViewer {
throw UnimplementedError();
}
@override
Future<RenderTarget> createRenderTarget(int width, int height, int textureHandle) {
// TODO: implement createRenderTarget
throw UnimplementedError();
}
@override
Future setRenderTarget(covariant RenderTarget renderTarget) {
// TODO: implement setRenderTarget
@@ -799,13 +787,7 @@ class ThermionViewerStub extends ThermionViewer {
// TODO: implement createHeadlessSwapChain
throw UnimplementedError();
}
@override
Future<Uint8List> capture({covariant SwapChain? swapChain, covariant View? view, covariant RenderTarget? renderTarget}) {
// TODO: implement capture
throw UnimplementedError();
}
@override
Future<SwapChain> createSwapChain(handle) {
// TODO: implement createSwapChain
@@ -1089,6 +1071,88 @@ class ThermionViewerStub extends ThermionViewer {
// TODO: implement setParent
throw UnimplementedError();
}
@override
Future<LinearImage> createImage(int width, int height, int channels) {
// TODO: implement createImage
throw UnimplementedError();
}
@override
Future<Texture> createTexture(int width, int height, {int depth = 1, int levels = 1, TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D, TextureFormat textureFormat = TextureFormat.RGBA32F}) {
// TODO: implement createTexture
throw UnimplementedError();
}
@override
Future<TextureSampler> createTextureSampler({TextureMinFilter minFilter = TextureMinFilter.LINEAR, TextureMagFilter magFilter = TextureMagFilter.LINEAR, TextureWrapMode wrapS = TextureWrapMode.CLAMP_TO_EDGE, TextureWrapMode wrapT = TextureWrapMode.CLAMP_TO_EDGE, TextureWrapMode wrapR = TextureWrapMode.CLAMP_TO_EDGE, double anisotropy = 0.0, TextureCompareMode compareMode = TextureCompareMode.NONE, TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) {
// TODO: implement createTextureSampler
throw UnimplementedError();
}
@override
Future<LinearImage> decodeImage(Uint8List data) {
// TODO: implement decodeImage
throw UnimplementedError();
}
@override
Future destroyCamera(covariant Camera camera) {
// TODO: implement destroyCamera
throw UnimplementedError();
}
@override
Future<bool> isCastShadowsEnabled(ThermionEntity entity) {
// TODO: implement isCastShadowsEnabled
throw UnimplementedError();
}
@override
Future<bool> isReceiveShadowsEnabled(ThermionEntity entity) {
// TODO: implement isReceiveShadowsEnabled
throw UnimplementedError();
}
@override
// TODO: implement msPerFrame
double get msPerFrame => throw UnimplementedError();
@override
Future setCastShadows(ThermionEntity entity, bool castShadows) {
// TODO: implement setCastShadows
throw UnimplementedError();
}
@override
Future setClearOptions(Vector4 clearColor, int clearStencil, bool clear, bool discard) {
// TODO: implement setClearOptions
throw UnimplementedError();
}
@override
Future setReceiveShadows(ThermionEntity entity, bool receiveShadows) {
// TODO: implement setReceiveShadows
throw UnimplementedError();
}
@override
Future<List<Uint8List>> capture(covariant List<({RenderTarget? renderTarget, SwapChain? swapChain, View view})> targets) {
// TODO: implement capture
throw UnimplementedError();
}
@override
Future<RenderTarget> createRenderTarget(int width, int height, {int? colorTextureHandle, int? depthTextureHandle}) {
// TODO: implement createRenderTarget
throw UnimplementedError();
}
@override
Future setBloom(bool enabled, double strength) {
// TODO: implement setBloom
throw UnimplementedError();
}
}

View File

@@ -1,3 +1,5 @@
import 'package:vector_math/vector_math_64.dart';
import '../../../viewer.dart';
class ThermionWasmMaterialInstance extends MaterialInstance {
@@ -94,4 +96,52 @@ class ThermionWasmMaterialInstance extends MaterialInstance {
// TODO: implement setStencilWriteEnabled
throw UnimplementedError();
}
@override
Future dispose() {
// TODO: implement dispose
throw UnimplementedError();
}
@override
Future setParameterBool(String name, bool value) {
// TODO: implement setParameterBool
throw UnimplementedError();
}
@override
Future setParameterFloat3(String name, double x, double y, double z) {
// TODO: implement setParameterFloat3
throw UnimplementedError();
}
@override
Future setParameterFloat3Array(String name, List<Vector3> data) {
// TODO: implement setParameterFloat3Array
throw UnimplementedError();
}
@override
Future setParameterTexture(String name, covariant Texture texture, covariant TextureSampler sampler) {
// TODO: implement setParameterTexture
throw UnimplementedError();
}
@override
Future setStencilReadMask(int mask) {
// TODO: implement setStencilReadMask
throw UnimplementedError();
}
@override
Future setStencilWriteMask(int mask) {
// TODO: implement setStencilWriteMask
throw UnimplementedError();
}
@override
Future setTransparencyMode(TransparencyMode mode) {
// TODO: implement setTransparencyMode
throw UnimplementedError();
}
}

View File

@@ -121,7 +121,7 @@
// [context!, loader, null, uberArchivePath?.toJS].toJS,
// null) as JSNumber;
// await createSwapChain(width.ceil(), height.ceil());
// updateViewportAndCameraProjection(width.ceil(), height.ceil(), 1.0);
// setViewportAndCameraProjection(width.ceil(), height.ceil(), 1.0);
// _sceneManager = _module!.ccall("get_scene_manager", "void*",
// ["void*".toJS].toJS, [_viewer!].toJS, null) as JSNumber;
@@ -177,7 +177,7 @@
// [_viewer!].toJS, null);
// }
// void updateViewportAndCameraProjection(
// void setViewportAndCameraProjection(
// int width, int height, double scaleFactor) {
// if (width == 0 || height == 0) {
// throw Exception("Width/height must be greater than zero");