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 {
Future<Vector3> getPosition() async {
final modelMatrix = await getModelMatrix();
return modelMatrix.getTranslation();
}
Future lookAt(Vector3 position, {Vector3? focus, Vector3? up}) async {
focus ??= Vector3.zero();
up ??= Vector3(0, 1, 0);

View File

@@ -6,7 +6,7 @@ class FilamentConfig<T, U> {
final Backend backend;
final T? renderCallback;
final U? renderCallbackOwner;
final U resourceLoader;
final Future<Uint8List> Function(String) resourceLoader;
final U? platform;
final U? driver;
final U? sharedContext;
@@ -32,7 +32,6 @@ abstract class FilamentApp<T> {
final T engine;
final T gltfAssetLoader;
final T gltfResourceLoader;
final T renderer;
final T transformManager;
final T lightManager;
@@ -42,7 +41,6 @@ abstract class FilamentApp<T> {
FilamentApp(
{required this.engine,
required this.gltfAssetLoader,
required this.gltfResourceLoader,
required this.renderer,
required this.transformManager,
required this.lightManager,
@@ -239,4 +237,15 @@ abstract class FilamentApp<T> {
///
///
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:io';
import 'dart:typed_data';
import 'package:path/path.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/ffi_asset.dart';
@@ -27,7 +29,6 @@ class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
class FFIFilamentApp extends FilamentApp<Pointer> {
final Pointer<TEngine> engine;
final Pointer<TGltfAssetLoader> gltfAssetLoader;
final Pointer<TGltfResourceLoader> gltfResourceLoader;
final Pointer<TRenderer> renderer;
final Pointer<TTransformManager> transformManager;
final Pointer<TLightManager> lightManager;
@@ -36,29 +37,35 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
final Pointer<TRenderTicker> renderTicker;
final Pointer<TNameComponentManager> nameComponentManager;
final Future<Uint8List> Function(String uri) resourceLoader;
FFIFilamentApp(
this.engine,
this.gltfAssetLoader,
this.gltfResourceLoader,
this.renderer,
this.transformManager,
this.lightManager,
this.renderableManager,
this.ubershaderMaterialProvider,
this.renderTicker,
this.nameComponentManager)
this.nameComponentManager,
this.resourceLoader)
: super(
engine: engine,
gltfAssetLoader: gltfAssetLoader,
gltfResourceLoader: gltfResourceLoader,
renderer: renderer,
transformManager: transformManager,
lightManager: lightManager,
renderableManager: renderableManager,
ubershaderMaterialProvider: ubershaderMaterialProvider) {}
static Future<Uint8List> _defaultResourceLoader(String path) {
print("Loading file $path");
return File(path).readAsBytes();
}
static Future create({FFIFilamentConfig? config}) async {
config ??= FFIFilamentConfig(resourceLoader: nullptr);
config ??= FFIFilamentConfig(resourceLoader: _defaultResourceLoader);
if (FilamentApp.instance != null) {
await FilamentApp.instance!.destroy();
}
@@ -75,8 +82,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
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>(
@@ -95,14 +100,14 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
FilamentApp.instance = FFIFilamentApp(
engine,
gltfAssetLoader,
gltfResourceLoader,
renderer,
transformManager,
lightManager,
renderableManager,
ubershaderMaterialProvider,
renderTicker,
nameComponentManager);
nameComponentManager,
config.resourceLoader);
}
final _views = <FFISwapChain, List<FFIView>>{};
@@ -220,7 +225,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
TextureFormat textureFormat = TextureFormat.RGBA16F,
int? importedTextureHandle}) async {
var bitmask = flags.fold(0, (a, b) => a | b.value);
final texturePtr = await withPointerCallback<TTexture>((cb) {
Texture_buildRenderThread(
engine,
@@ -238,7 +243,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
throw Exception("Failed to create texture");
}
return FFITexture(
engine!,
engine,
texturePtr,
);
}
@@ -256,24 +261,24 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
TextureCompareMode compareMode = TextureCompareMode.NONE,
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
final samplerPtr = TextureSampler_create();
// TextureSampler_setMinFilter(
// samplerPtr, TSamplerMinFilter.values[minFilter.index]);
// TextureSampler_setMagFilter(
// samplerPtr, TSamplerMagFilter.values[magFilter.index]);
// TextureSampler_setWrapModeS(
// samplerPtr, TSamplerWrapMode.values[wrapS.index]);
// TextureSampler_setWrapModeT(
// samplerPtr, TSamplerWrapMode.values[wrapT.index]);
// TextureSampler_setWrapModeR(
// samplerPtr, TSamplerWrapMode.values[wrapR.index]);
// if (anisotropy > 0) {
// TextureSampler_setAnisotropy(samplerPtr, anisotropy);
// }
TextureSampler_setMinFilter(
samplerPtr, TSamplerMinFilter.values[minFilter.index]);
TextureSampler_setMagFilter(
samplerPtr, TSamplerMagFilter.values[magFilter.index]);
TextureSampler_setWrapModeS(
samplerPtr, TSamplerWrapMode.values[wrapS.index]);
TextureSampler_setWrapModeT(
samplerPtr, TSamplerWrapMode.values[wrapT.index]);
TextureSampler_setWrapModeR(
samplerPtr, TSamplerWrapMode.values[wrapR.index]);
if (anisotropy > 0) {
TextureSampler_setAnisotropy(samplerPtr, anisotropy);
}
// TextureSampler_setCompareMode(
// samplerPtr,
// TSamplerCompareMode.values[compareMode.index],
// TSamplerCompareFunc.values[compareFunc.index]);
TextureSampler_setCompareMode(
samplerPtr,
TSamplerCompareMode.values[compareMode.index],
TSamplerCompareFunc.values[compareFunc.index]);
return FFITextureSampler(samplerPtr);
}
@@ -307,7 +312,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
///
Future<Material> createMaterial(Uint8List data) async {
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);
}
@@ -614,4 +619,80 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
Future setClearColor(double r, double g, double b, double a) async {
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.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.Pointer<TTexture> Function(
ffi.Pointer<TEngine>,
@@ -802,246 +1036,6 @@ external void TextureSampler_destroy(
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.Pointer<TGizmo> Function(ffi.Pointer<TEngine>, ffi.Pointer<TView>,
ffi.UnsignedInt)>(symbol: "Gizmo_create", isLeaf: true)
@@ -1999,9 +1993,8 @@ external void SceneAsset_destroyRenderThread(
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TEngine>,
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TNameComponentManager>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
@@ -2011,9 +2004,8 @@ external void SceneAsset_destroyRenderThread(
.NativeFunction<ffi.Void Function(ffi.Pointer<TSceneAsset>)>>)>(
isLeaf: true)
external void SceneAsset_loadGlbRenderThread(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TNameComponentManager> tNameComponentManager,
ffi.Pointer<ffi.Uint8> data,
int length,
@@ -2600,22 +2592,60 @@ external void GltfAssetLoader_createRenderThread(
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<TGltfResourceLoader>)>>)>(isLeaf: true)
external void GltfResourceLoader_createRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Char> relativeResourcePath,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TGltfResourceLoader>)>>
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.Void Function(
ffi.Pointer<TGltfAssetLoader>,
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.Size,
ffi.Uint8,
@@ -2623,8 +2653,8 @@ external void GltfResourceLoader_createRenderThread(
ffi.NativeFunction<
ffi.Void Function(ffi.Pointer<TFilamentAsset>)>>)>(isLeaf: true)
external void GltfAssetLoader_loadRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<ffi.Uint8> data,
int length,
int numInstances,
@@ -2642,6 +2672,48 @@ external void Scene_addFilamentAssetRenderThread(
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.Void Function(ffi.Pointer<TRenderableManager>, EntityId, ffi.Int,
ffi.Pointer<TMaterialInstance>)>(isLeaf: true)
@@ -2987,17 +3059,15 @@ external ffi.Pointer<TSceneAsset> SceneAsset_createGeometry(
@ffi.Native<
ffi.Pointer<TSceneAsset> Function(
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TGltfResourceLoader>,
ffi.Pointer<TEngine>,
ffi.Pointer<TGltfAssetLoader>,
ffi.Pointer<TNameComponentManager>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Size)>(isLeaf: true)
external ffi.Pointer<TSceneAsset> SceneAsset_loadGlb(
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
ffi.Pointer<TNameComponentManager> tNameComponentManager,
ffi.Pointer<ffi.Uint8> data,
int length,
@@ -3023,6 +3093,24 @@ external ffi.Pointer<TSceneAsset> SceneAsset_loadGltf(
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.Pointer<TSceneAsset> Function(
ffi.Pointer<TEngine>, ffi.Pointer<TMaterial>)>(isLeaf: true)
@@ -3815,6 +3903,70 @@ enum TLightType {
typedef EntityId = ffi.Int32;
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 {
SAMPLER_2D(0),
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 {
X(0),
Y(1),

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:thermion_dart/src/filament/src/light_options.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 FFIScene scene;
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) {
throw Exception("FilamentApp has not been created");
}
@@ -191,7 +190,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future setBackgroundImage(String path, {bool fillHeight = false}) async {
final imageData = await loadAsset(path);
final imageData = await loadAssetFromUri(path);
_backgroundImage ??= await BackgroundImage.create(this, scene);
await _backgroundImage!.setImage(imageData);
}
@@ -224,7 +223,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future loadSkybox(String skyboxPath) async {
var data = await loadAsset(skyboxPath);
var data = await loadAssetFromUri(skyboxPath);
skybox = await withPointerCallback<TSkybox>((cb) {
Engine_buildSkyboxRenderThread(
@@ -242,7 +241,7 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
var data = await loadAsset(lightingPath);
var data = await loadAssetFromUri(lightingPath);
indirectLight = await withPointerCallback<TIndirectLight>((cb) {
Engine_buildIndirectLightRenderThread(
app.engine, data.address, data.length, intensity, cb, nullptr);
@@ -313,7 +312,7 @@ class ThermionViewerFFI extends ThermionViewer {
// LightManager_setSunHaloFalloff(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
LightManager_setShadowCaster(
app.lightManager, entity, directLight.castShadows);
Scene_addEntity(scene.scene, entity);
_lights.add(entity);
@@ -349,11 +348,11 @@ class ThermionViewerFFI extends ThermionViewer {
///
@override
Future<ThermionAsset> loadGlb(String path,
{int numInstances = 1, bool keepData = false}) async {
final data = await loadAsset(path);
{int numInstances = 1, bool keepData = false, String? relativeResourcePath}) async {
final data = await loadAssetFromUri(path);
return loadGlbFromBuffer(data,
numInstances: numInstances, keepData: keepData);
numInstances: numInstances, keepData: keepData, relativeResourcePath: relativeResourcePath);
}
///
@@ -365,52 +364,22 @@ class ThermionViewerFFI extends ThermionViewer {
bool keepData = false,
int priority = 4,
int layer = 0,
bool loadResourcesAsync = false}) async {
var asset = await withPointerCallback<TSceneAsset>((cb) =>
SceneAsset_loadGlbRenderThread(
app.gltfAssetLoader,
app.gltfResourceLoader,
app.engine,
app.nameComponentManager,
data.address,
data.length,
numInstances,
cb));
bool loadResourcesAsync = false,
String? relativeResourcePath}) async {
var asset = await FilamentApp.instance!.loadGlbFromBuffer(data, animationManager,
numInstances: numInstances,
keepData: keepData,
priority: priority,
layer: layer,
loadResourcesAsync: loadResourcesAsync,
relativeResourcePath:relativeResourcePath
) as FFIAsset;
_assets.add(asset);
if (asset == nullptr) {
throw Exception("An error occurred loading the asset");
}
await scene.add(asset);
var thermionAsset = FFIAsset(asset, app, animationManager);
_assets.add(thermionAsset);
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);
return asset;
}
///

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.
///
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.
@@ -145,17 +147,8 @@ abstract class ThermionViewer {
bool keepData = false,
int priority = 4,
int layer = 0,
bool loadResourcesAsync = false});
///
/// 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});
bool loadResourcesAsync = false,
String relativeResourcePath});
///
/// 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
#define _T_GLTF_ASSET_LOADER_H
#pragma once
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#include "TMaterialInstance.h"
#include "TTexture.h"
#ifdef __cplusplus
extern "C"
@@ -12,10 +9,10 @@ extern "C"
#endif
EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider);
EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine);
EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
uint8_t *data,
size_t length,
uint8_t numInstances
@@ -27,4 +24,3 @@ EMSCRIPTEN_KEEPALIVE TMaterialProvider *GltfAssetLoader_getMaterialProvider(TGlt
}
#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(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager,
uint8_t *data,
size_t length,
@@ -43,6 +42,16 @@ extern "C"
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 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_loadGlbRenderThread(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager,
uint8_t *data,
size_t length,
@@ -250,10 +249,14 @@ namespace thermion
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 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(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
uint8_t *data,
size_t length,
uint8_t numInstances,

View File

@@ -41,7 +41,7 @@ namespace thermion
_materialInstances(materialInstances),
_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();

View File

@@ -33,18 +33,6 @@ namespace thermion
#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) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
@@ -66,18 +54,23 @@ EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine,
}
EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tGltfResourceLoader,
uint8_t *data,
size_t length,
uint8_t numInstances)
{
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
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)
{
@@ -85,11 +78,15 @@ EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load(
return std::nullptr_t();
}
if (!resourceLoader->loadResources(asset))
{
Log("Unknown error loading glb asset");
return std::nullptr_t();
const char *const *const resourceUris = asset->getResourceUris();
const size_t resourceUriCount = asset->getResourceUriCount();
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);
}

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(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager,
uint8_t *data,
size_t length,
@@ -77,20 +76,61 @@ extern "C"
) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
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 *assetLoader = reinterpret_cast<filament::gltfio::AssetLoader *>(tAssetLoader);
auto *resourceLoader = reinterpret_cast<filament::gltfio::ResourceLoader *>(tResourceLoader);
auto *sceneAsset = new GltfSceneAsset(
filamentAsset,
assetLoader,
engine,
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) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
auto *material = reinterpret_cast<filament::Material *>(tMaterial);

View File

@@ -9,6 +9,7 @@
#include "c_api/TAnimationManager.h"
#include "c_api/TEngine.h"
#include "c_api/TGltfAssetLoader.h"
#include "c_api/TGltfResourceLoader.h"
#include "c_api/TRenderer.h"
#include "c_api/TRenderTicker.h"
#include "c_api/TRenderTarget.h"
@@ -18,12 +19,9 @@
#include "c_api/TView.h"
#include "c_api/ThermionDartRenderThreadApi.h"
#include "rendering/RenderLoop.hpp"
#include "Log.hpp"
#include "ThreadPool.hpp"
using namespace thermion;
using namespace std::chrono_literals;
#include <time.h>
@@ -360,9 +358,8 @@ extern "C"
}
EMSCRIPTEN_KEEPALIVE void SceneAsset_loadGlbRenderThread(
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager,
uint8_t *data,
size_t length,
@@ -372,7 +369,7 @@ extern "C"
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);
});
auto fut = _rl->add_task(lambda);
@@ -875,19 +872,54 @@ extern "C"
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(
[=]() mutable
{
auto loader = GltfResourceLoader_create(tEngine);
auto loader = GltfResourceLoader_create(tEngine, relativeResourcePath);
callback(loader);
});
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(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tResourceLoader,
uint8_t *data,
size_t length,
uint8_t numInstances,
@@ -896,7 +928,7 @@ extern "C"
std::packaged_task<void()> lambda(
[=]() mutable
{
auto loader = GltfAssetLoader_load(tAssetLoader, tResourceLoader, data, length, numInstances);
auto loader = GltfAssetLoader_load(tEngine, tAssetLoader, data, length, numInstances);
callback(loader);
});
auto fut = _rl->add_task(lambda);