refactoring

This commit is contained in:
Nick Fisher
2025-03-20 18:48:04 +08:00
parent cbff4cd805
commit e6bdcb687a
16 changed files with 780 additions and 541 deletions

View File

@@ -5,6 +5,11 @@ enum Projection { Perspective, Orthographic }
abstract class Camera { abstract class Camera {
Future<Vector3> getPosition() async {
final modelMatrix = await getModelMatrix();
return modelMatrix.getTranslation();
}
Future lookAt(Vector3 position, {Vector3? focus, Vector3? up}) async { Future lookAt(Vector3 position, {Vector3? focus, Vector3? up}) async {
focus ??= Vector3.zero(); focus ??= Vector3.zero();
up ??= Vector3(0, 1, 0); up ??= Vector3(0, 1, 0);

View File

@@ -6,7 +6,7 @@ class FilamentConfig<T, U> {
final Backend backend; final Backend backend;
final T? renderCallback; final T? renderCallback;
final U? renderCallbackOwner; final U? renderCallbackOwner;
final U resourceLoader; final Future<Uint8List> Function(String) resourceLoader;
final U? platform; final U? platform;
final U? driver; final U? driver;
final U? sharedContext; final U? sharedContext;
@@ -32,7 +32,6 @@ abstract class FilamentApp<T> {
final T engine; final T engine;
final T gltfAssetLoader; final T gltfAssetLoader;
final T gltfResourceLoader;
final T renderer; final T renderer;
final T transformManager; final T transformManager;
final T lightManager; final T lightManager;
@@ -42,7 +41,6 @@ abstract class FilamentApp<T> {
FilamentApp( FilamentApp(
{required this.engine, {required this.engine,
required this.gltfAssetLoader, required this.gltfAssetLoader,
required this.gltfResourceLoader,
required this.renderer, required this.renderer,
required this.transformManager, required this.transformManager,
required this.lightManager, required this.lightManager,
@@ -239,4 +237,15 @@ abstract class FilamentApp<T> {
/// ///
/// ///
Future setClearColor(double r, double g, double b, double a); Future setClearColor(double r, double g, double b, double a);
///
///
///
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data, T animationManager,
{int numInstances = 1,
bool keepData = false,
int priority = 4,
int layer = 0,
bool loadResourcesAsync = false,
String? relativeResourcePath});
} }

View File

@@ -1,6 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:path/path.dart';
import 'package:thermion_dart/src/filament/src/engine.dart'; import 'package:thermion_dart/src/filament/src/engine.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
@@ -27,7 +29,6 @@ class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
class FFIFilamentApp extends FilamentApp<Pointer> { class FFIFilamentApp extends FilamentApp<Pointer> {
final Pointer<TEngine> engine; final Pointer<TEngine> engine;
final Pointer<TGltfAssetLoader> gltfAssetLoader; final Pointer<TGltfAssetLoader> gltfAssetLoader;
final Pointer<TGltfResourceLoader> gltfResourceLoader;
final Pointer<TRenderer> renderer; final Pointer<TRenderer> renderer;
final Pointer<TTransformManager> transformManager; final Pointer<TTransformManager> transformManager;
final Pointer<TLightManager> lightManager; final Pointer<TLightManager> lightManager;
@@ -36,29 +37,35 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
final Pointer<TRenderTicker> renderTicker; final Pointer<TRenderTicker> renderTicker;
final Pointer<TNameComponentManager> nameComponentManager; final Pointer<TNameComponentManager> nameComponentManager;
final Future<Uint8List> Function(String uri) resourceLoader;
FFIFilamentApp( FFIFilamentApp(
this.engine, this.engine,
this.gltfAssetLoader, this.gltfAssetLoader,
this.gltfResourceLoader,
this.renderer, this.renderer,
this.transformManager, this.transformManager,
this.lightManager, this.lightManager,
this.renderableManager, this.renderableManager,
this.ubershaderMaterialProvider, this.ubershaderMaterialProvider,
this.renderTicker, this.renderTicker,
this.nameComponentManager) this.nameComponentManager,
this.resourceLoader)
: super( : super(
engine: engine, engine: engine,
gltfAssetLoader: gltfAssetLoader, gltfAssetLoader: gltfAssetLoader,
gltfResourceLoader: gltfResourceLoader,
renderer: renderer, renderer: renderer,
transformManager: transformManager, transformManager: transformManager,
lightManager: lightManager, lightManager: lightManager,
renderableManager: renderableManager, renderableManager: renderableManager,
ubershaderMaterialProvider: ubershaderMaterialProvider) {} ubershaderMaterialProvider: ubershaderMaterialProvider) {}
static Future<Uint8List> _defaultResourceLoader(String path) {
print("Loading file $path");
return File(path).readAsBytes();
}
static Future create({FFIFilamentConfig? config}) async { static Future create({FFIFilamentConfig? config}) async {
config ??= FFIFilamentConfig(resourceLoader: nullptr); config ??= FFIFilamentConfig(resourceLoader: _defaultResourceLoader);
if (FilamentApp.instance != null) { if (FilamentApp.instance != null) {
await FilamentApp.instance!.destroy(); await FilamentApp.instance!.destroy();
} }
@@ -75,8 +82,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
config.disableHandleUseAfterFreeCheck, config.disableHandleUseAfterFreeCheck,
cb)); cb));
final gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
(cb) => GltfResourceLoader_createRenderThread(engine, cb));
final gltfAssetLoader = await withPointerCallback<TGltfAssetLoader>( final gltfAssetLoader = await withPointerCallback<TGltfAssetLoader>(
(cb) => GltfAssetLoader_createRenderThread(engine, nullptr, cb)); (cb) => GltfAssetLoader_createRenderThread(engine, nullptr, cb));
final renderer = await withPointerCallback<TRenderer>( final renderer = await withPointerCallback<TRenderer>(
@@ -95,14 +100,14 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
FilamentApp.instance = FFIFilamentApp( FilamentApp.instance = FFIFilamentApp(
engine, engine,
gltfAssetLoader, gltfAssetLoader,
gltfResourceLoader,
renderer, renderer,
transformManager, transformManager,
lightManager, lightManager,
renderableManager, renderableManager,
ubershaderMaterialProvider, ubershaderMaterialProvider,
renderTicker, renderTicker,
nameComponentManager); nameComponentManager,
config.resourceLoader);
} }
final _views = <FFISwapChain, List<FFIView>>{}; final _views = <FFISwapChain, List<FFIView>>{};
@@ -238,7 +243,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
throw Exception("Failed to create texture"); throw Exception("Failed to create texture");
} }
return FFITexture( return FFITexture(
engine!, engine,
texturePtr, texturePtr,
); );
} }
@@ -256,24 +261,24 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
TextureCompareMode compareMode = TextureCompareMode.NONE, TextureCompareMode compareMode = TextureCompareMode.NONE,
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async { TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
final samplerPtr = TextureSampler_create(); final samplerPtr = TextureSampler_create();
// TextureSampler_setMinFilter( TextureSampler_setMinFilter(
// samplerPtr, TSamplerMinFilter.values[minFilter.index]); samplerPtr, TSamplerMinFilter.values[minFilter.index]);
// TextureSampler_setMagFilter( TextureSampler_setMagFilter(
// samplerPtr, TSamplerMagFilter.values[magFilter.index]); samplerPtr, TSamplerMagFilter.values[magFilter.index]);
// TextureSampler_setWrapModeS( TextureSampler_setWrapModeS(
// samplerPtr, TSamplerWrapMode.values[wrapS.index]); samplerPtr, TSamplerWrapMode.values[wrapS.index]);
// TextureSampler_setWrapModeT( TextureSampler_setWrapModeT(
// samplerPtr, TSamplerWrapMode.values[wrapT.index]); samplerPtr, TSamplerWrapMode.values[wrapT.index]);
// TextureSampler_setWrapModeR( TextureSampler_setWrapModeR(
// samplerPtr, TSamplerWrapMode.values[wrapR.index]); samplerPtr, TSamplerWrapMode.values[wrapR.index]);
// if (anisotropy > 0) { if (anisotropy > 0) {
// TextureSampler_setAnisotropy(samplerPtr, anisotropy); TextureSampler_setAnisotropy(samplerPtr, anisotropy);
// } }
// TextureSampler_setCompareMode( TextureSampler_setCompareMode(
// samplerPtr, samplerPtr,
// TSamplerCompareMode.values[compareMode.index], TSamplerCompareMode.values[compareMode.index],
// TSamplerCompareFunc.values[compareFunc.index]); TSamplerCompareFunc.values[compareFunc.index]);
return FFITextureSampler(samplerPtr); return FFITextureSampler(samplerPtr);
} }
@@ -307,7 +312,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
/// ///
Future<Material> createMaterial(Uint8List data) async { Future<Material> createMaterial(Uint8List data) async {
var ptr = await withPointerCallback<TMaterial>((cb) { var ptr = await withPointerCallback<TMaterial>((cb) {
Engine_buildMaterialRenderThread(engine!, data.address, data.length, cb); Engine_buildMaterialRenderThread(engine, data.address, data.length, cb);
}); });
return FFIMaterial(ptr, this); return FFIMaterial(ptr, this);
} }
@@ -614,4 +619,80 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
Future setClearColor(double r, double g, double b, double a) async { Future setClearColor(double r, double g, double b, double a) async {
Renderer_setClearOptions(renderer, r, g, b, a, 0, true, false); Renderer_setClearOptions(renderer, r, g, b, a, 0, true, false);
} }
///
///
///
Future<ThermionAsset> loadGlbFromBuffer(
Uint8List data, Pointer animationManager,
{int numInstances = 1,
bool keepData = false,
int priority = 4,
int layer = 0,
String? relativeResourcePath,
bool loadResourcesAsync = false}) async {
if (relativeResourcePath != null && !relativeResourcePath!.endsWith("/")) {
relativeResourcePath = "$relativeResourcePath/";
}
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
(cb) => GltfResourceLoader_createRenderThread(engine,
relativeResourcePath?.toNativeUtf8().cast<Char>() ?? nullptr, cb));
var asset = await withPointerCallback<TSceneAsset>((cb) =>
SceneAsset_loadGlbRenderThread(engine, gltfAssetLoader,
nameComponentManager, data.address, data.length, numInstances, cb));
if (asset == nullptr) {
throw Exception("An error occurred loading the asset");
}
var resourceUris = SceneAsset_getResourceUris(asset);
var resourceUriCount = SceneAsset_getResourceUriCount(asset);
final resources = <FinalizableUint8List>[];
for (int i = 0; i < resourceUriCount; i++) {
final resourceUriDart = resourceUris[i].cast<Utf8>().toDartString();
final resourceData = await resourceLoader(relativeResourcePath == null
? resourceUriDart
: "$relativeResourcePath/$resourceUriDart");
resources.add(FinalizableUint8List(resourceUris[i], resourceData));
await withVoidCallback((cb) =>
GltfResourceLoader_addResourceDataRenderThread(
gltfResourceLoader,
resourceUris[i],
resourceData.address,
resourceData.lengthInBytes,
cb));
}
if (loadResourcesAsync) {
// GltfResourceLoader_asyncBeginLoad(gltfResourceLoader)
throw UnimplementedError(
"TODO"); // need to use a NativeFinalizer to ensure the pointer is still valid until resource loader has finished
} else {
final filamentAsset = SceneAsset_getFilamentAsset(asset);
if (filamentAsset == nullptr) {
throw Exception();
}
final result = await withBoolCallback((cb) =>
GltfResourceLoader_loadResourcesRenderThread(
gltfResourceLoader, filamentAsset, cb));
if (!result) {
throw Exception("Failed to load resources");
}
}
await withVoidCallback((cb) =>
GltfResourceLoader_destroyRenderThread(engine, gltfResourceLoader, cb));
return FFIAsset(asset, this, animationManager.cast<TAnimationManager>());
}
}
class FinalizableUint8List implements Finalizable {
final Pointer name;
final Uint8List data;
FinalizableUint8List(this.name, this.data);
} }

View File

@@ -430,6 +430,240 @@ external void FilamentAsset_getEntities(
ffi.Pointer<EntityId> out, ffi.Pointer<EntityId> out,
); );
@ffi.Native<
ffi.Pointer<TGltfAssetLoader> Function(
ffi.Pointer<TEngine>, ffi.Pointer<TMaterialProvider>)>(isLeaf: true)
external ffi.Pointer<TGltfAssetLoader> GltfAssetLoader_create(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TMaterialProvider> tMaterialProvider,
);
@ffi.Native<
ffi.Pointer<TFilamentAsset> Function(
ffi.Pointer<TEngine>,
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Uint8)>(isLeaf: true)
external ffi.Pointer<TFilamentAsset> GltfAssetLoader_load(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<ffi.Uint8> data,
int length,
int numInstances,
);
@ffi.Native<
ffi.Pointer<TMaterialInstance> Function(ffi.Pointer<TRenderableManager>,
ffi.Pointer<TFilamentAsset>)>(isLeaf: true)
external ffi.Pointer<TMaterialInstance> GltfAssetLoader_getMaterialInstance(
ffi.Pointer<TRenderableManager> tRenderableManager,
ffi.Pointer<TFilamentAsset> tAsset,
);
@ffi.Native<
ffi.Pointer<TMaterialProvider> Function(
ffi.Pointer<TGltfAssetLoader>)>(isLeaf: true)
external ffi.Pointer<TMaterialProvider> GltfAssetLoader_getMaterialProvider(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
);
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
external TViewport View_getViewport(
ffi.Pointer<TView> view,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
isLeaf: true)
external void View_setViewport(
ffi.Pointer<TView> view,
int width,
int height,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TRenderTarget>)>(
isLeaf: true)
external void View_setRenderTarget(
ffi.Pointer<TView> view,
ffi.Pointer<TRenderTarget> renderTarget,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setFrustumCullingEnabled(
ffi.Pointer<TView> view,
bool enabled,
);
@ffi.Native<ffi.Pointer<TRenderTarget> Function(ffi.Pointer<TView>)>(
isLeaf: true)
external ffi.Pointer<TRenderTarget> View_getRenderTarget(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setPostProcessing(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setShadowsEnabled(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Int)>(isLeaf: true)
external void View_setShadowType(
ffi.Pointer<TView> tView,
int shadowType,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Float, ffi.Float)>(
isLeaf: true)
external void View_setSoftShadowOptions(
ffi.Pointer<TView> tView,
double penumbraScale,
double penumbraRatioScale,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool, ffi.Float)>(
isLeaf: true)
external void View_setBloom(
ffi.Pointer<TView> tView,
bool enabled,
double strength,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.UnsignedInt)>(
symbol: "View_setRenderQuality", isLeaf: true)
external void _View_setRenderQuality(
ffi.Pointer<TView> tView,
int qualityLevel,
);
void View_setRenderQuality(
ffi.Pointer<TView> tView,
TQualityLevel qualityLevel,
) =>
_View_setRenderQuality(
tView,
qualityLevel.value,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TEngine>,
ffi.UnsignedInt)>(symbol: "View_setToneMapping", isLeaf: true)
external void _View_setToneMapping(
ffi.Pointer<TView> tView,
ffi.Pointer<TEngine> tEngine,
int toneMapping,
);
void View_setToneMapping(
ffi.Pointer<TView> tView,
ffi.Pointer<TEngine> tEngine,
TToneMapping toneMapping,
) =>
_View_setToneMapping(
tView,
tEngine,
toneMapping.value,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TView>, ffi.Bool, ffi.Bool, ffi.Bool)>(isLeaf: true)
external void View_setAntiAliasing(
ffi.Pointer<TView> tView,
bool msaa,
bool fxaa,
bool taa,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Int, ffi.Bool)>(
isLeaf: true)
external void View_setLayerEnabled(
ffi.Pointer<TView> tView,
int layer,
bool visible,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TCamera>)>(
isLeaf: true)
external void View_setCamera(
ffi.Pointer<TView> tView,
ffi.Pointer<TCamera> tCamera,
);
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TView>)>(isLeaf: true)
external ffi.Pointer<TScene> View_getScene(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TView>)>(isLeaf: true)
external ffi.Pointer<TCamera> View_getCamera(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setStencilBufferEnabled(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Bool Function(ffi.Pointer<TView>)>(isLeaf: true)
external bool View_isStencilBufferEnabled(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setDitheringEnabled(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Bool Function(ffi.Pointer<TView>)>(isLeaf: true)
external bool View_isDitheringEnabled(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TScene>)>(
isLeaf: true)
external void View_setScene(
ffi.Pointer<TView> tView,
ffi.Pointer<TScene> tScene,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32, ffi.Uint32,
PickCallback)>(isLeaf: true)
external void View_pick(
ffi.Pointer<TView> tView,
int requestId,
int x,
int y,
PickCallback callback,
);
@ffi.Native<ffi.Pointer<TNameComponentManager> Function()>(isLeaf: true)
external ffi.Pointer<TNameComponentManager> NameComponentManager_create();
@ffi.Native<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<TNameComponentManager>, EntityId)>(isLeaf: true)
external ffi.Pointer<ffi.Char> NameComponentManager_getName(
ffi.Pointer<TNameComponentManager> tNameComponentManager,
int entity,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TIndirectLight>, ffi.Pointer<ffi.Double>)>(isLeaf: true)
external void IndirectLight_setRotation(
ffi.Pointer<TIndirectLight> tIndirectLight,
ffi.Pointer<ffi.Double> rotation,
);
@ffi.Native< @ffi.Native<
ffi.Pointer<TTexture> Function( ffi.Pointer<TTexture> Function(
ffi.Pointer<TEngine>, ffi.Pointer<TEngine>,
@@ -802,246 +1036,6 @@ external void TextureSampler_destroy(
ffi.Pointer<TTextureSampler> sampler, ffi.Pointer<TTextureSampler> sampler,
); );
@ffi.Native<
ffi.Pointer<TGltfAssetLoader> Function(
ffi.Pointer<TEngine>, ffi.Pointer<TMaterialProvider>)>(isLeaf: true)
external ffi.Pointer<TGltfAssetLoader> GltfAssetLoader_create(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TMaterialProvider> tMaterialProvider,
);
@ffi.Native<ffi.Pointer<TGltfResourceLoader> Function(ffi.Pointer<TEngine>)>(
isLeaf: true)
external ffi.Pointer<TGltfResourceLoader> GltfResourceLoader_create(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<
ffi.Pointer<TFilamentAsset> Function(
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Uint8)>(isLeaf: true)
external ffi.Pointer<TFilamentAsset> GltfAssetLoader_load(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<ffi.Uint8> data,
int length,
int numInstances,
);
@ffi.Native<
ffi.Pointer<TMaterialInstance> Function(ffi.Pointer<TRenderableManager>,
ffi.Pointer<TFilamentAsset>)>(isLeaf: true)
external ffi.Pointer<TMaterialInstance> GltfAssetLoader_getMaterialInstance(
ffi.Pointer<TRenderableManager> tRenderableManager,
ffi.Pointer<TFilamentAsset> tAsset,
);
@ffi.Native<
ffi.Pointer<TMaterialProvider> Function(
ffi.Pointer<TGltfAssetLoader>)>(isLeaf: true)
external ffi.Pointer<TMaterialProvider> GltfAssetLoader_getMaterialProvider(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
);
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
external TViewport View_getViewport(
ffi.Pointer<TView> view,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
isLeaf: true)
external void View_setViewport(
ffi.Pointer<TView> view,
int width,
int height,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TRenderTarget>)>(
isLeaf: true)
external void View_setRenderTarget(
ffi.Pointer<TView> view,
ffi.Pointer<TRenderTarget> renderTarget,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setFrustumCullingEnabled(
ffi.Pointer<TView> view,
bool enabled,
);
@ffi.Native<ffi.Pointer<TRenderTarget> Function(ffi.Pointer<TView>)>(
isLeaf: true)
external ffi.Pointer<TRenderTarget> View_getRenderTarget(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setPostProcessing(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setShadowsEnabled(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Int)>(isLeaf: true)
external void View_setShadowType(
ffi.Pointer<TView> tView,
int shadowType,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Float, ffi.Float)>(
isLeaf: true)
external void View_setSoftShadowOptions(
ffi.Pointer<TView> tView,
double penumbraScale,
double penumbraRatioScale,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool, ffi.Float)>(
isLeaf: true)
external void View_setBloom(
ffi.Pointer<TView> tView,
bool enabled,
double strength,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.UnsignedInt)>(
symbol: "View_setRenderQuality", isLeaf: true)
external void _View_setRenderQuality(
ffi.Pointer<TView> tView,
int qualityLevel,
);
void View_setRenderQuality(
ffi.Pointer<TView> tView,
TQualityLevel qualityLevel,
) =>
_View_setRenderQuality(
tView,
qualityLevel.value,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TEngine>,
ffi.UnsignedInt)>(symbol: "View_setToneMapping", isLeaf: true)
external void _View_setToneMapping(
ffi.Pointer<TView> tView,
ffi.Pointer<TEngine> tEngine,
int toneMapping,
);
void View_setToneMapping(
ffi.Pointer<TView> tView,
ffi.Pointer<TEngine> tEngine,
TToneMapping toneMapping,
) =>
_View_setToneMapping(
tView,
tEngine,
toneMapping.value,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TView>, ffi.Bool, ffi.Bool, ffi.Bool)>(isLeaf: true)
external void View_setAntiAliasing(
ffi.Pointer<TView> tView,
bool msaa,
bool fxaa,
bool taa,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Int, ffi.Bool)>(
isLeaf: true)
external void View_setLayerEnabled(
ffi.Pointer<TView> tView,
int layer,
bool visible,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TCamera>)>(
isLeaf: true)
external void View_setCamera(
ffi.Pointer<TView> tView,
ffi.Pointer<TCamera> tCamera,
);
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TView>)>(isLeaf: true)
external ffi.Pointer<TScene> View_getScene(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TView>)>(isLeaf: true)
external ffi.Pointer<TCamera> View_getCamera(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setStencilBufferEnabled(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Bool Function(ffi.Pointer<TView>)>(isLeaf: true)
external bool View_isStencilBufferEnabled(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
external void View_setDitheringEnabled(
ffi.Pointer<TView> tView,
bool enabled,
);
@ffi.Native<ffi.Bool Function(ffi.Pointer<TView>)>(isLeaf: true)
external bool View_isDitheringEnabled(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TScene>)>(
isLeaf: true)
external void View_setScene(
ffi.Pointer<TView> tView,
ffi.Pointer<TScene> tScene,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32, ffi.Uint32,
PickCallback)>(isLeaf: true)
external void View_pick(
ffi.Pointer<TView> tView,
int requestId,
int x,
int y,
PickCallback callback,
);
@ffi.Native<ffi.Pointer<TNameComponentManager> Function()>(isLeaf: true)
external ffi.Pointer<TNameComponentManager> NameComponentManager_create();
@ffi.Native<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<TNameComponentManager>, EntityId)>(isLeaf: true)
external ffi.Pointer<ffi.Char> NameComponentManager_getName(
ffi.Pointer<TNameComponentManager> tNameComponentManager,
int entity,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TIndirectLight>, ffi.Pointer<ffi.Double>)>(isLeaf: true)
external void IndirectLight_setRotation(
ffi.Pointer<TIndirectLight> tIndirectLight,
ffi.Pointer<ffi.Double> rotation,
);
@ffi.Native< @ffi.Native<
ffi.Pointer<TGizmo> Function(ffi.Pointer<TEngine>, ffi.Pointer<TView>, ffi.Pointer<TGizmo> Function(ffi.Pointer<TEngine>, ffi.Pointer<TView>,
ffi.UnsignedInt)>(symbol: "Gizmo_create", isLeaf: true) ffi.UnsignedInt)>(symbol: "Gizmo_create", isLeaf: true)
@@ -1999,9 +1993,8 @@ external void SceneAsset_destroyRenderThread(
@ffi.Native< @ffi.Native<
ffi.Void Function( ffi.Void Function(
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TEngine>, ffi.Pointer<TEngine>,
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TNameComponentManager>, ffi.Pointer<TNameComponentManager>,
ffi.Pointer<ffi.Uint8>, ffi.Pointer<ffi.Uint8>,
ffi.Size, ffi.Size,
@@ -2011,9 +2004,8 @@ external void SceneAsset_destroyRenderThread(
.NativeFunction<ffi.Void Function(ffi.Pointer<TSceneAsset>)>>)>( .NativeFunction<ffi.Void Function(ffi.Pointer<TSceneAsset>)>>)>(
isLeaf: true) isLeaf: true)
external void SceneAsset_loadGlbRenderThread( external void SceneAsset_loadGlbRenderThread(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<TEngine> tEngine, ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TNameComponentManager> tNameComponentManager, ffi.Pointer<TNameComponentManager> tNameComponentManager,
ffi.Pointer<ffi.Uint8> data, ffi.Pointer<ffi.Uint8> data,
int length, int length,
@@ -2600,22 +2592,60 @@ external void GltfAssetLoader_createRenderThread(
@ffi.Native< @ffi.Native<
ffi.Void Function( ffi.Void Function(
ffi.Pointer<TEngine>, ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Char>,
ffi.Pointer< ffi.Pointer<
ffi.NativeFunction< ffi.NativeFunction<
ffi.Void Function( ffi.Void Function(
ffi.Pointer<TGltfResourceLoader>)>>)>(isLeaf: true) ffi.Pointer<TGltfResourceLoader>)>>)>(isLeaf: true)
external void GltfResourceLoader_createRenderThread( external void GltfResourceLoader_createRenderThread(
ffi.Pointer<TEngine> tEngine, ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Char> relativeResourcePath,
ffi.Pointer< ffi.Pointer<
ffi ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TGltfResourceLoader>)>> .NativeFunction<ffi.Void Function(ffi.Pointer<TGltfResourceLoader>)>>
callback, callback,
); );
@ffi.Native<
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void GltfResourceLoader_destroyRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TFilamentAsset>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>(
isLeaf: true)
external void GltfResourceLoader_loadResourcesRenderThread(
ffi.Pointer<TGltfResourceLoader> tGltfResourceLoader,
ffi.Pointer<TFilamentAsset> tFilamentAsset,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> callback,
);
@ffi.Native< @ffi.Native<
ffi.Void Function( ffi.Void Function(
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TGltfResourceLoader>, ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void GltfResourceLoader_addResourceDataRenderThread(
ffi.Pointer<TGltfResourceLoader> tGltfResourceLoader,
ffi.Pointer<ffi.Char> uri,
ffi.Pointer<ffi.Uint8> data,
int length,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<ffi.Uint8>, ffi.Pointer<ffi.Uint8>,
ffi.Size, ffi.Size,
ffi.Uint8, ffi.Uint8,
@@ -2623,8 +2653,8 @@ external void GltfResourceLoader_createRenderThread(
ffi.NativeFunction< ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<TFilamentAsset>)>>)>(isLeaf: true) ffi.Void Function(ffi.Pointer<TFilamentAsset>)>>)>(isLeaf: true)
external void GltfAssetLoader_loadRenderThread( external void GltfAssetLoader_loadRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader, ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<ffi.Uint8> data, ffi.Pointer<ffi.Uint8> data,
int length, int length,
int numInstances, int numInstances,
@@ -2642,6 +2672,48 @@ external void Scene_addFilamentAssetRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback, ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
); );
@ffi.Native<
ffi.Pointer<TGltfResourceLoader> Function(
ffi.Pointer<TEngine>, ffi.Pointer<ffi.Char>)>(isLeaf: true)
external ffi.Pointer<TGltfResourceLoader> GltfResourceLoader_create(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Char> relativeResourcePath,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>, ffi.Pointer<TGltfResourceLoader>)>(isLeaf: true)
external void GltfResourceLoader_destroy(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfResourceLoader> tGltfResourceLoader,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TFilamentAsset>)>(isLeaf: true)
external void GltfResourceLoader_asyncBeginLoad(
ffi.Pointer<TGltfResourceLoader> tGltfResourceLoader,
ffi.Pointer<TFilamentAsset> tFilamentAsset,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TGltfResourceLoader>, ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Uint8>, ffi.Size)>(isLeaf: true)
external void GltfResourceLoader_addResourceData(
ffi.Pointer<TGltfResourceLoader> tGltfResourceLoader,
ffi.Pointer<ffi.Char> uri,
ffi.Pointer<ffi.Uint8> data,
int length,
);
@ffi.Native<
ffi.Bool Function(ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TFilamentAsset>)>(isLeaf: true)
external bool GltfResourceLoader_loadResources(
ffi.Pointer<TGltfResourceLoader> tGltfResourceLoader,
ffi.Pointer<TFilamentAsset> tFilamentAsset,
);
@ffi.Native< @ffi.Native<
ffi.Void Function(ffi.Pointer<TRenderableManager>, EntityId, ffi.Int, ffi.Void Function(ffi.Pointer<TRenderableManager>, EntityId, ffi.Int,
ffi.Pointer<TMaterialInstance>)>(isLeaf: true) ffi.Pointer<TMaterialInstance>)>(isLeaf: true)
@@ -2987,17 +3059,15 @@ external ffi.Pointer<TSceneAsset> SceneAsset_createGeometry(
@ffi.Native< @ffi.Native<
ffi.Pointer<TSceneAsset> Function( ffi.Pointer<TSceneAsset> Function(
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TEngine>, ffi.Pointer<TEngine>,
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TNameComponentManager>, ffi.Pointer<TNameComponentManager>,
ffi.Pointer<ffi.Uint8>, ffi.Pointer<ffi.Uint8>,
ffi.Size, ffi.Size,
ffi.Size)>(isLeaf: true) ffi.Size)>(isLeaf: true)
external ffi.Pointer<TSceneAsset> SceneAsset_loadGlb( external ffi.Pointer<TSceneAsset> SceneAsset_loadGlb(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<TEngine> tEngine, ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TNameComponentManager> tNameComponentManager, ffi.Pointer<TNameComponentManager> tNameComponentManager,
ffi.Pointer<ffi.Uint8> data, ffi.Pointer<ffi.Uint8> data,
int length, int length,
@@ -3023,6 +3093,24 @@ external ffi.Pointer<TSceneAsset> SceneAsset_loadGltf(
int numInstances, int numInstances,
); );
@ffi.Native<ffi.Int32 Function(ffi.Pointer<TSceneAsset>)>(isLeaf: true)
external int SceneAsset_getResourceUriCount(
ffi.Pointer<TSceneAsset> tSceneAsset,
);
@ffi.Native<
ffi.Pointer<ffi.Pointer<ffi.Char>> Function(
ffi.Pointer<TSceneAsset>)>(isLeaf: true)
external ffi.Pointer<ffi.Pointer<ffi.Char>> SceneAsset_getResourceUris(
ffi.Pointer<TSceneAsset> tSceneAsset,
);
@ffi.Native<ffi.Pointer<TFilamentAsset> Function(ffi.Pointer<TSceneAsset>)>(
isLeaf: true)
external ffi.Pointer<TFilamentAsset> SceneAsset_getFilamentAsset(
ffi.Pointer<TSceneAsset> tSceneAsset,
);
@ffi.Native< @ffi.Native<
ffi.Pointer<TSceneAsset> Function( ffi.Pointer<TSceneAsset> Function(
ffi.Pointer<TEngine>, ffi.Pointer<TMaterial>)>(isLeaf: true) ffi.Pointer<TEngine>, ffi.Pointer<TMaterial>)>(isLeaf: true)
@@ -3815,6 +3903,70 @@ enum TLightType {
typedef EntityId = ffi.Int32; typedef EntityId = ffi.Int32;
typedef DartEntityId = int; typedef DartEntityId = int;
final class TViewport extends ffi.Struct {
@ffi.Int32()
external int left;
@ffi.Int32()
external int bottom;
@ffi.Uint32()
external int width;
@ffi.Uint32()
external int height;
}
enum TToneMapping {
ACES(0),
FILMIC(1),
LINEAR(2);
final int value;
const TToneMapping(this.value);
static TToneMapping fromValue(int value) => switch (value) {
0 => ACES,
1 => FILMIC,
2 => LINEAR,
_ => throw ArgumentError("Unknown value for TToneMapping: $value"),
};
}
enum TQualityLevel {
LOW(0),
MEDIUM(1),
HIGH(2),
ULTRA(3);
final int value;
const TQualityLevel(this.value);
static TQualityLevel fromValue(int value) => switch (value) {
0 => LOW,
1 => MEDIUM,
2 => HIGH,
3 => ULTRA,
_ => throw ArgumentError("Unknown value for TQualityLevel: $value"),
};
}
typedef PickCallback = ffi.Pointer<ffi.NativeFunction<PickCallbackFunction>>;
typedef PickCallbackFunction = ffi.Void Function(
ffi.Uint32 requestId,
EntityId entityId,
ffi.Float depth,
ffi.Float fragX,
ffi.Float fragY,
ffi.Float fragZ);
typedef DartPickCallbackFunction = void Function(
int requestId,
DartEntityId entityId,
double depth,
double fragX,
double fragY,
double fragZ);
enum TTextureSamplerType { enum TTextureSamplerType {
SAMPLER_2D(0), SAMPLER_2D(0),
SAMPLER_2D_ARRAY(1), SAMPLER_2D_ARRAY(1),
@@ -4258,70 +4410,6 @@ enum TSamplerCompareMode {
}; };
} }
final class TViewport extends ffi.Struct {
@ffi.Int32()
external int left;
@ffi.Int32()
external int bottom;
@ffi.Uint32()
external int width;
@ffi.Uint32()
external int height;
}
enum TToneMapping {
ACES(0),
FILMIC(1),
LINEAR(2);
final int value;
const TToneMapping(this.value);
static TToneMapping fromValue(int value) => switch (value) {
0 => ACES,
1 => FILMIC,
2 => LINEAR,
_ => throw ArgumentError("Unknown value for TToneMapping: $value"),
};
}
enum TQualityLevel {
LOW(0),
MEDIUM(1),
HIGH(2),
ULTRA(3);
final int value;
const TQualityLevel(this.value);
static TQualityLevel fromValue(int value) => switch (value) {
0 => LOW,
1 => MEDIUM,
2 => HIGH,
3 => ULTRA,
_ => throw ArgumentError("Unknown value for TQualityLevel: $value"),
};
}
typedef PickCallback = ffi.Pointer<ffi.NativeFunction<PickCallbackFunction>>;
typedef PickCallbackFunction = ffi.Void Function(
ffi.Uint32 requestId,
EntityId entityId,
ffi.Float depth,
ffi.Float fragX,
ffi.Float fragY,
ffi.Float fragZ);
typedef DartPickCallbackFunction = void Function(
int requestId,
DartEntityId entityId,
double depth,
double fragX,
double fragY,
double fragZ);
enum TGizmoAxis { enum TGizmoAxis {
X(0), X(0),
Y(1), Y(1),

View File

@@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:thermion_dart/src/filament/src/light_options.dart'; import 'package:thermion_dart/src/filament/src/light_options.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/background_image.dart'; import 'package:thermion_dart/src/viewer/src/ffi/src/background_image.dart';
@@ -39,12 +38,12 @@ class ThermionViewerFFI extends ThermionViewer {
late final FFIView view; late final FFIView view;
late final FFIScene scene; late final FFIScene scene;
late final Pointer<TAnimationManager> animationManager; late final Pointer<TAnimationManager> animationManager;
late final Future<Uint8List> Function(String path) loadAsset; late final Future<Uint8List> Function(String path) loadAssetFromUri;
/// ///
/// ///
/// ///
ThermionViewerFFI({required this.loadAsset, this.renderTarget}) { ThermionViewerFFI({required this.loadAssetFromUri, this.renderTarget}) {
if (FilamentApp.instance == null) { if (FilamentApp.instance == null) {
throw Exception("FilamentApp has not been created"); throw Exception("FilamentApp has not been created");
} }
@@ -191,7 +190,7 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future setBackgroundImage(String path, {bool fillHeight = false}) async { Future setBackgroundImage(String path, {bool fillHeight = false}) async {
final imageData = await loadAsset(path); final imageData = await loadAssetFromUri(path);
_backgroundImage ??= await BackgroundImage.create(this, scene); _backgroundImage ??= await BackgroundImage.create(this, scene);
await _backgroundImage!.setImage(imageData); await _backgroundImage!.setImage(imageData);
} }
@@ -224,7 +223,7 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future loadSkybox(String skyboxPath) async { Future loadSkybox(String skyboxPath) async {
var data = await loadAsset(skyboxPath); var data = await loadAssetFromUri(skyboxPath);
skybox = await withPointerCallback<TSkybox>((cb) { skybox = await withPointerCallback<TSkybox>((cb) {
Engine_buildSkyboxRenderThread( Engine_buildSkyboxRenderThread(
@@ -242,7 +241,7 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future loadIbl(String lightingPath, {double intensity = 30000}) async { Future loadIbl(String lightingPath, {double intensity = 30000}) async {
var data = await loadAsset(lightingPath); var data = await loadAssetFromUri(lightingPath);
indirectLight = await withPointerCallback<TIndirectLight>((cb) { indirectLight = await withPointerCallback<TIndirectLight>((cb) {
Engine_buildIndirectLightRenderThread( Engine_buildIndirectLightRenderThread(
app.engine, data.address, data.length, intensity, cb, nullptr); app.engine, data.address, data.length, intensity, cb, nullptr);
@@ -349,11 +348,11 @@ class ThermionViewerFFI extends ThermionViewer {
/// ///
@override @override
Future<ThermionAsset> loadGlb(String path, Future<ThermionAsset> loadGlb(String path,
{int numInstances = 1, bool keepData = false}) async { {int numInstances = 1, bool keepData = false, String? relativeResourcePath}) async {
final data = await loadAsset(path); final data = await loadAssetFromUri(path);
return loadGlbFromBuffer(data, return loadGlbFromBuffer(data,
numInstances: numInstances, keepData: keepData); numInstances: numInstances, keepData: keepData, relativeResourcePath: relativeResourcePath);
} }
/// ///
@@ -365,52 +364,22 @@ class ThermionViewerFFI extends ThermionViewer {
bool keepData = false, bool keepData = false,
int priority = 4, int priority = 4,
int layer = 0, int layer = 0,
bool loadResourcesAsync = false}) async { bool loadResourcesAsync = false,
var asset = await withPointerCallback<TSceneAsset>((cb) => String? relativeResourcePath}) async {
SceneAsset_loadGlbRenderThread( var asset = await FilamentApp.instance!.loadGlbFromBuffer(data, animationManager,
app.gltfAssetLoader, numInstances: numInstances,
app.gltfResourceLoader, keepData: keepData,
app.engine, priority: priority,
app.nameComponentManager, layer: layer,
data.address, loadResourcesAsync: loadResourcesAsync,
data.length, relativeResourcePath:relativeResourcePath
numInstances, ) as FFIAsset;
cb));
if (asset == nullptr) { _assets.add(asset);
throw Exception("An error occurred loading the asset");
}
var thermionAsset = FFIAsset(asset, app, animationManager); await scene.add(asset);
_assets.add(thermionAsset); return asset;
await scene.add(thermionAsset);
return thermionAsset;
}
///
///
///
@override
Future<ThermionAsset> loadGltf(String path, String relativeResourcePath,
{bool keepData = false}) async {
throw UnimplementedError();
// final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
// final relativeResourcePathPtr =
// relativeResourcePath.toNativeUtf8(allocator: allocator).cast<Char>();
// var assetPtr = await withPointerCallback<TSceneAsset>((callback) =>
// SceneManager_loadGltfRenderThread(_sceneManager!, pathPtr,
// relativeResourcePathPtr, keepData, callback));
// allocator.free(pathPtr);
// allocator.free(relativeResourcePathPtr);
// if (assetPtr == nullptr) {
// throw Exception("An error occurred loading the asset at $path");
// }
// return FFIAsset(
// assetPtr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
} }
/// ///

View File

@@ -129,7 +129,9 @@ abstract class ThermionViewer {
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception. /// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
/// ///
Future<ThermionAsset> loadGlb(String path, Future<ThermionAsset> loadGlb(String path,
{int numInstances = 1, bool keepData = false}); {int numInstances = 1,
bool keepData = false,
String relativeResourcePath});
/// ///
/// Load the .glb asset from the specified buffer, adding all entities to the scene. /// Load the .glb asset from the specified buffer, adding all entities to the scene.
@@ -145,17 +147,8 @@ abstract class ThermionViewer {
bool keepData = false, bool keepData = false,
int priority = 4, int priority = 4,
int layer = 0, int layer = 0,
bool loadResourcesAsync = false}); bool loadResourcesAsync = false,
String relativeResourcePath});
///
/// Load the .gltf asset at the given path, adding all entities to the scene.
/// [relativeResourcePath] is the folder path where the glTF resources are stored;
/// this is usually the parent directory of the .gltf file itself.
///
/// See [loadGlb] for an explanation of [keepData].
///
Future<ThermionAsset> loadGltf(String path, String relativeResourcePath,
{bool keepData = false});
/// ///
/// Destroys [asset] and all underlying resources /// Destroys [asset] and all underlying resources

View File

@@ -1,79 +0,0 @@
/*
* This file is licensed under the zlib/libpng license, included in this
* distribution in the file COPYING.
*/
#include <future>
#include <thread>
#include <deque>
#include <vector>
#include <utility>
#include <chrono>
#include <functional>
#include <type_traits>
#ifndef _THREADPOOL_HPP
#define _THREADPOOL_HPP
namespace thermion {
class ThreadPool {
std::vector<std::thread> pool;
bool stop;
std::mutex access;
std::condition_variable cond;
std::deque<std::function<void()>> tasks;
public:
explicit ThreadPool(int nr = 1) : stop(false) {
while(nr-->0) {
add_worker();
}
}
~ThreadPool() {
stop = true;
for(std::thread &t : pool) {
t.join();
}
pool.clear();
}
template<class Rt>
auto add_task(std::packaged_task<Rt()>& pt) -> std::future<Rt> {
std::unique_lock<std::mutex> lock(access);
auto ret = pt.get_future();
tasks.push_back([pt=std::make_shared<std::packaged_task<Rt()>>(std::move(pt))]{ (*pt)();});
cond.notify_one();
return ret;
}
private:
void add_worker() {
std::thread t([this]() {
while(!stop || tasks.size() > 0) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(access);
if(tasks.empty()) {
cond.wait_for(lock, std::chrono::duration<int, std::milli>(5));
continue;
}
task = std::move(tasks.front());
tasks.pop_front();
}
task();
}
});
pool.push_back(std::move(t));
}
};
}
#endif//_THREADPOOL_HPP
// vim: syntax=cpp11

View File

@@ -1,10 +1,7 @@
#ifndef _T_GLTF_ASSET_LOADER_H #pragma once
#define _T_GLTF_ASSET_LOADER_H
#include "APIExport.h" #include "APIExport.h"
#include "APIBoundaryTypes.h" #include "APIBoundaryTypes.h"
#include "TMaterialInstance.h"
#include "TTexture.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@@ -12,10 +9,10 @@ extern "C"
#endif #endif
EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider); EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider);
EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine);
EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load( EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader, TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
uint8_t numInstances uint8_t numInstances
@@ -27,4 +24,3 @@ EMSCRIPTEN_KEEPALIVE TMaterialProvider *GltfAssetLoader_getMaterialProvider(TGlt
} }
#endif #endif
#endif

View File

@@ -0,0 +1,21 @@
#pragma once
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine, const char *relativeResourcePath);
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroy(TEngine *tEngine, TGltfResourceLoader *tGltfResourceLoader);
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncBeginLoad(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset);
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceData(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length);
EMSCRIPTEN_KEEPALIVE bool GltfResourceLoader_loadResources(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset);
#ifdef __cplusplus
}
#endif

View File

@@ -24,9 +24,8 @@ extern "C"
); );
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb( EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine, TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager, TNameComponentManager *tNameComponentManager,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
@@ -43,6 +42,16 @@ extern "C"
size_t numInstances size_t numInstances
); );
EMSCRIPTEN_KEEPALIVE int32_t SceneAsset_getResourceUriCount(
TSceneAsset *tSceneAsset
);
EMSCRIPTEN_KEEPALIVE const char* const* SceneAsset_getResourceUris(
TSceneAsset *tSceneAsset
);
EMSCRIPTEN_KEEPALIVE TFilamentAsset *SceneAsset_getFilamentAsset(TSceneAsset *tSceneAsset);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createGrid(TEngine *tEngine, TMaterial * tMaterial); EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createGrid(TEngine *tEngine, TMaterial * tMaterial);
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroy(TSceneAsset *tSceneAsset); EMSCRIPTEN_KEEPALIVE void SceneAsset_destroy(TSceneAsset *tSceneAsset);

View File

@@ -85,9 +85,8 @@ namespace thermion
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)()); EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread( EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine, TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager, TNameComponentManager *tNameComponentManager,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
@@ -250,10 +249,14 @@ namespace thermion
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, void (*callback)()); EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, void (*callback)());
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *)); EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, void (*callback)(TGltfResourceLoader *)); EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)());
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, void (*callback)());
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread( EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader, TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
uint8_t numInstances, uint8_t numInstances,

View File

@@ -41,7 +41,7 @@ namespace thermion
_materialInstances(materialInstances), _materialInstances(materialInstances),
_materialInstanceCount(materialInstanceCount) _materialInstanceCount(materialInstanceCount)
{ {
TRACE("Created GltfSceneAsset with %d reserved instances", asset->getAssetInstanceCount()); TRACE("Created GltfSceneAsset from FilamentAsset %d with %d reserved instances", asset, asset->getAssetInstanceCount());
} }
~GltfSceneAsset(); ~GltfSceneAsset();

View File

@@ -33,18 +33,6 @@ namespace thermion
#endif #endif
EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine) {
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto *gltfResourceLoader = new gltfio::ResourceLoader({.engine = engine,
.normalizeSkinningWeights = true});
auto stbDecoder = gltfio::createStbProvider(engine);
auto ktxDecoder = gltfio::createKtx2Provider(engine);
gltfResourceLoader->addTextureProvider("image/ktx2", ktxDecoder);
gltfResourceLoader->addTextureProvider("image/png", stbDecoder);
gltfResourceLoader->addTextureProvider("image/jpeg", stbDecoder);
return reinterpret_cast<TGltfResourceLoader *>(gltfResourceLoader);
}
EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider) { EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine); auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
@@ -66,18 +54,23 @@ EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine,
} }
EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load( EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader, TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tGltfResourceLoader,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
uint8_t numInstances) uint8_t numInstances)
{ {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
auto *assetLoader = reinterpret_cast<gltfio::AssetLoader *>(tAssetLoader); auto *assetLoader = reinterpret_cast<gltfio::AssetLoader *>(tAssetLoader);
auto *resourceLoader = reinterpret_cast<gltfio::ResourceLoader *>(tGltfResourceLoader);
std::vector<gltfio::FilamentInstance *> instances(numInstances); gltfio::FilamentAsset *asset;
gltfio::FilamentAsset *asset = assetLoader->createInstancedAsset((const uint8_t *)data, length, instances.data(), numInstances); if(numInstances > 1) {
std::vector<gltfio::FilamentInstance *> instances(numInstances);
asset = assetLoader->createInstancedAsset((const uint8_t *)data, length, instances.data(), numInstances);
} else {
asset = assetLoader->createAsset((const uint8_t *)data, length);
}
if (!asset) if (!asset)
{ {
@@ -85,11 +78,15 @@ EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load(
return std::nullptr_t(); return std::nullptr_t();
} }
if (!resourceLoader->loadResources(asset)) const char *const *const resourceUris = asset->getResourceUris();
{ const size_t resourceUriCount = asset->getResourceUriCount();
Log("Unknown error loading glb asset");
return std::nullptr_t(); Log("glTF asset : %d resource URIs, %d instances", resourceUriCount, numInstances);
for(int i = 0; i < resourceUriCount; i++) {
Log("%s", resourceUris[i]);
} }
return reinterpret_cast<TFilamentAsset *>(asset); return reinterpret_cast<TFilamentAsset *>(asset);
} }

View File

@@ -0,0 +1,75 @@
#include "c_api/TGltfResourceLoader.h"
#include <filament/Engine.h>
#include <filament/Fence.h>
#include <filament/Material.h>
#include <filament/RenderableManager.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/Texture.h>
#include <filament/TextureSampler.h>
#include <filament/TransformManager.h>
#include <filament/View.h>
#include <gltfio/Animator.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/ResourceLoader.h>
#include <gltfio/TextureProvider.h>
#include <gltfio/math.h>
#include <gltfio/materials/uberarchive.h>
#include <utils/EntityManager.h>
#include <utils/NameComponentManager.h>
#include "Log.hpp"
#ifdef __cplusplus
namespace thermion
{
extern "C"
{
using namespace filament;
#endif
EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine, const char *relativeResourcePath) {
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto *gltfResourceLoader = new gltfio::ResourceLoader({
.engine = engine,
.gltfPath = relativeResourcePath
});
auto stbDecoder = gltfio::createStbProvider(engine);
auto ktxDecoder = gltfio::createKtx2Provider(engine);
gltfResourceLoader->addTextureProvider("image/ktx2", ktxDecoder);
gltfResourceLoader->addTextureProvider("image/png", stbDecoder);
gltfResourceLoader->addTextureProvider("image/jpeg", stbDecoder);
return reinterpret_cast<TGltfResourceLoader *>(gltfResourceLoader);
}
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroy(TEngine *tEngine, TGltfResourceLoader *tGltfResourceLoader) {
auto *gltfResourceLoader = reinterpret_cast<gltfio::ResourceLoader *>(tGltfResourceLoader);
delete gltfResourceLoader;
}
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceData(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length) {
TRACE("Adding data (length %d) for glTF resource URI %s", length, uri);
auto *gltfResourceLoader = reinterpret_cast<gltfio::ResourceLoader *>(tGltfResourceLoader);
for(int i = 0; i < 8; i++) {
std::cout << static_cast<uint32_t>(data[i]) << " ";
}
std::cout << std::endl;
gltfResourceLoader->addResourceData(uri, { data, length});
}
EMSCRIPTEN_KEEPALIVE bool GltfResourceLoader_loadResources(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset) {
auto *gltfResourceLoader = reinterpret_cast<gltfio::ResourceLoader *>(tGltfResourceLoader);
auto *filamentAsset = reinterpret_cast<gltfio::FilamentAsset *>(tFilamentAsset);
return gltfResourceLoader->loadResources(filamentAsset);
}
#ifdef __cplusplus
}
}
#endif

View File

@@ -67,9 +67,8 @@ extern "C"
} }
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb( EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_loadGlb(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine, TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager, TNameComponentManager *tNameComponentManager,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
@@ -77,20 +76,61 @@ extern "C"
) { ) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine); auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
auto *nameComponentManager = reinterpret_cast<utils::NameComponentManager *>(tNameComponentManager); auto *nameComponentManager = reinterpret_cast<utils::NameComponentManager *>(tNameComponentManager);
auto *tFilamentAsset = GltfAssetLoader_load(tAssetLoader, tResourceLoader, data, length, numInstances); auto *tFilamentAsset = GltfAssetLoader_load(tEngine, tAssetLoader, data, length, numInstances);
auto *filamentAsset = reinterpret_cast<filament::gltfio::FilamentAsset *>(tFilamentAsset); auto *filamentAsset = reinterpret_cast<filament::gltfio::FilamentAsset *>(tFilamentAsset);
auto *assetLoader = reinterpret_cast<filament::gltfio::AssetLoader *>(tAssetLoader); auto *assetLoader = reinterpret_cast<filament::gltfio::AssetLoader *>(tAssetLoader);
auto *resourceLoader = reinterpret_cast<filament::gltfio::ResourceLoader *>(tResourceLoader);
auto *sceneAsset = new GltfSceneAsset( auto *sceneAsset = new GltfSceneAsset(
filamentAsset, filamentAsset,
assetLoader, assetLoader,
engine, engine,
nameComponentManager nameComponentManager
); );
return reinterpret_cast<TSceneAsset *>(sceneAsset);
return reinterpret_cast<TSceneAsset *>(sceneAsset);
} }
EMSCRIPTEN_KEEPALIVE int32_t SceneAsset_getResourceUriCount(
TSceneAsset *tSceneAsset
) {
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
Log("Error - not a gltf asset");
return -1;
}
auto gltfAsset = reinterpret_cast<GltfSceneAsset *>(tSceneAsset);
auto *filamentAsset = gltfAsset->getAsset();
return filamentAsset->getResourceUriCount();
}
EMSCRIPTEN_KEEPALIVE const char* const* SceneAsset_getResourceUris(
TSceneAsset *tSceneAsset
) {
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
Log("Error - not a gltf asset");
return nullptr;
}
auto gltfAsset = reinterpret_cast<GltfSceneAsset *>(tSceneAsset);
auto *filamentAsset = gltfAsset->getAsset();
return filamentAsset->getResourceUris();
}
EMSCRIPTEN_KEEPALIVE TFilamentAsset *SceneAsset_getFilamentAsset(TSceneAsset *tSceneAsset) {
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
Log("Error - not a gltf asset");
return nullptr;
}
auto gltfAsset = reinterpret_cast<GltfSceneAsset *>(tSceneAsset);
auto *filamentAsset = gltfAsset->getAsset();
TRACE("SceneAsset %d FilamentAsset %d", sceneAsset, filamentAsset);
return reinterpret_cast<TFilamentAsset *>(filamentAsset);
}
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createGrid(TEngine *tEngine, TMaterial* tMaterial) { EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_createGrid(TEngine *tEngine, TMaterial* tMaterial) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine); auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
auto *material = reinterpret_cast<filament::Material *>(tMaterial); auto *material = reinterpret_cast<filament::Material *>(tMaterial);

View File

@@ -9,6 +9,7 @@
#include "c_api/TAnimationManager.h" #include "c_api/TAnimationManager.h"
#include "c_api/TEngine.h" #include "c_api/TEngine.h"
#include "c_api/TGltfAssetLoader.h" #include "c_api/TGltfAssetLoader.h"
#include "c_api/TGltfResourceLoader.h"
#include "c_api/TRenderer.h" #include "c_api/TRenderer.h"
#include "c_api/TRenderTicker.h" #include "c_api/TRenderTicker.h"
#include "c_api/TRenderTarget.h" #include "c_api/TRenderTarget.h"
@@ -18,12 +19,9 @@
#include "c_api/TView.h" #include "c_api/TView.h"
#include "c_api/ThermionDartRenderThreadApi.h" #include "c_api/ThermionDartRenderThreadApi.h"
#include "rendering/RenderLoop.hpp" #include "rendering/RenderLoop.hpp"
#include "Log.hpp" #include "Log.hpp"
#include "ThreadPool.hpp"
using namespace thermion; using namespace thermion;
using namespace std::chrono_literals; using namespace std::chrono_literals;
#include <time.h> #include <time.h>
@@ -360,9 +358,8 @@ extern "C"
} }
EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread( EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine, TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager, TNameComponentManager *tNameComponentManager,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
@@ -372,7 +369,7 @@ extern "C"
std::packaged_task<void()> lambda( std::packaged_task<void()> lambda(
[=] [=]
{ {
auto sceneAsset = SceneAsset_loadGlb(tAssetLoader, tResourceLoader, tEngine, tNameComponentManager, data, length, numInstances); auto sceneAsset = SceneAsset_loadGlb(tEngine, tAssetLoader, tNameComponentManager, data, length, numInstances);
callback(sceneAsset); callback(sceneAsset);
}); });
auto fut = _rl->add_task(lambda); auto fut = _rl->add_task(lambda);
@@ -875,19 +872,54 @@ extern "C"
auto fut = _rl->add_task(lambda); auto fut = _rl->add_task(lambda);
} }
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, void (*callback)(TGltfResourceLoader *)) { EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *)) {
std::packaged_task<void()> lambda( std::packaged_task<void()> lambda(
[=]() mutable [=]() mutable
{ {
auto loader = GltfResourceLoader_create(tEngine); auto loader = GltfResourceLoader_create(tEngine, relativeResourcePath);
callback(loader); callback(loader);
}); });
auto fut = _rl->add_task(lambda); auto fut = _rl->add_task(lambda);
} }
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)()) {
std::packaged_task<void()> lambda(
[=]() mutable
{
GltfResourceLoader_destroy(tEngine, tResourceLoader);
callback();
});
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool)) {
std::packaged_task<void()> lambda(
[=]() mutable
{
auto result = GltfResourceLoader_loadResources(tGltfResourceLoader, tFilamentAsset);
callback(result);
});
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceDataRenderThread(
TGltfResourceLoader *tGltfResourceLoader,
const char *uri,
uint8_t *data,
size_t length,
void (*callback)()) {
std::packaged_task<void()> lambda(
[=]() mutable
{
GltfResourceLoader_addResourceData(tGltfResourceLoader, uri, data, length);
callback();
});
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread( EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader, TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
uint8_t *data, uint8_t *data,
size_t length, size_t length,
uint8_t numInstances, uint8_t numInstances,
@@ -896,7 +928,7 @@ extern "C"
std::packaged_task<void()> lambda( std::packaged_task<void()> lambda(
[=]() mutable [=]() mutable
{ {
auto loader = GltfAssetLoader_load(tAssetLoader, tResourceLoader, data, length, numInstances); auto loader = GltfAssetLoader_load(tEngine, tAssetLoader, data, length, numInstances);
callback(loader); callback(loader);
}); });
auto fut = _rl->add_task(lambda); auto fut = _rl->add_task(lambda);