more refactoring
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
@@ -10,34 +11,18 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
///
|
||||
///
|
||||
final Pointer<TSceneAsset> pointer;
|
||||
final Pointer<TSceneAsset> asset;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
final Pointer<TSceneManager> sceneManager;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Pointer<TRenderableManager> get renderableManager =>
|
||||
Engine_getRenderableManager(engine);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
final Pointer<TEngine> engine;
|
||||
final FFIFilamentApp app;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
FFIAsset? _highlight;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
final Pointer<TMaterialProvider> _unlitMaterialProvider;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -48,22 +33,15 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
late final ThermionEntity entity;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
final ThermionViewer viewer;
|
||||
|
||||
FFIAsset(this.pointer, this.sceneManager, this.engine,
|
||||
this._unlitMaterialProvider, this.viewer,
|
||||
{this.isInstance = false}) {
|
||||
entity = SceneAsset_getEntity(pointer);
|
||||
FFIAsset(this.asset, this.app, {this.isInstance = false}) {
|
||||
entity = SceneAsset_getEntity(asset);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ThermionEntity>> getChildEntities() async {
|
||||
var count = SceneAsset_getChildEntityCount(pointer);
|
||||
var count = SceneAsset_getChildEntityCount(asset);
|
||||
var children = Int32List(count);
|
||||
SceneAsset_getChildEntities(pointer, children.address);
|
||||
SceneAsset_getChildEntities(asset, children.address);
|
||||
return children;
|
||||
}
|
||||
|
||||
@@ -73,12 +51,11 @@ class FFIAsset extends ThermionAsset {
|
||||
throw Exception(
|
||||
"This is itself an instance. Call getInstance on the original asset that this instance was created from");
|
||||
}
|
||||
var instance = SceneAsset_getInstance(pointer, index);
|
||||
var instance = SceneAsset_getInstance(asset, index);
|
||||
if (instance == nullptr) {
|
||||
throw Exception("No instance available at index $index");
|
||||
}
|
||||
return FFIAsset(
|
||||
instance, sceneManager, engine, _unlitMaterialProvider, viewer);
|
||||
return FFIAsset(instance, app);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -100,7 +77,7 @@ class FFIAsset extends ThermionAsset {
|
||||
}
|
||||
|
||||
SceneAsset_createInstanceRenderThread(
|
||||
pointer,
|
||||
asset,
|
||||
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
||||
materialInstances?.length ?? 0,
|
||||
cb);
|
||||
@@ -108,8 +85,7 @@ class FFIAsset extends ThermionAsset {
|
||||
if (created == FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("Failed to create instance");
|
||||
}
|
||||
return FFIAsset(
|
||||
created, sceneManager, engine, _unlitMaterialProvider, viewer);
|
||||
return FFIAsset(created, app);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -117,7 +93,7 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
@override
|
||||
Future<int> getInstanceCount() async {
|
||||
return SceneAsset_getInstanceCount(pointer);
|
||||
return SceneAsset_getInstanceCount(asset);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -127,8 +103,7 @@ class FFIAsset extends ThermionAsset {
|
||||
Future<List<ThermionAsset>> getInstances() async {
|
||||
var count = await getInstanceCount();
|
||||
final result = List<ThermionAsset>.generate(count, (i) {
|
||||
return FFIAsset(SceneAsset_getInstance(pointer, i), sceneManager, engine,
|
||||
_unlitMaterialProvider, viewer);
|
||||
return FFIAsset(SceneAsset_getInstance(asset, i), app);
|
||||
});
|
||||
|
||||
return result;
|
||||
@@ -139,13 +114,14 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
@override
|
||||
Future removeStencilHighlight() async {
|
||||
if (_highlight != null) {
|
||||
SceneManager_removeFromScene(sceneManager, _highlight!.entity);
|
||||
final childEntities = await _highlight!.getChildEntities();
|
||||
for (final child in childEntities) {
|
||||
SceneManager_removeFromScene(sceneManager, child);
|
||||
}
|
||||
}
|
||||
throw UnimplementedError();
|
||||
// if (_highlight != null) {
|
||||
// SceneManager_removeFromScene(sceneManager, _highlight!.entity);
|
||||
// final childEntities = await _highlight!.getChildEntities();
|
||||
// for (final child in childEntities) {
|
||||
// SceneManager_removeFromScene(sceneManager, child);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
///
|
||||
@@ -165,8 +141,7 @@ class FFIAsset extends ThermionAsset {
|
||||
}
|
||||
var sourceMaterialInstance = FFIMaterialInstance(
|
||||
RenderableManager_getMaterialInstanceAt(
|
||||
renderableManager, targetEntity, 0),
|
||||
sceneManager);
|
||||
app.renderableManager, targetEntity, 0), app);
|
||||
|
||||
await sourceMaterialInstance.setStencilWriteEnabled(true);
|
||||
await sourceMaterialInstance.setDepthWriteEnabled(true);
|
||||
@@ -179,10 +154,10 @@ class FFIAsset extends ThermionAsset {
|
||||
await withPointerCallback<TMaterialInstance>((cb) {
|
||||
final key = Struct.create<TMaterialKey>();
|
||||
MaterialProvider_createMaterialInstanceRenderThread(
|
||||
_unlitMaterialProvider, key.address, cb);
|
||||
app.ubershaderMaterialProvider, key.address, cb);
|
||||
});
|
||||
final highlightMaterialInstance =
|
||||
FFIMaterialInstance(materialInstancePtr, sceneManager);
|
||||
FFIMaterialInstance(materialInstancePtr, app);
|
||||
await highlightMaterialInstance
|
||||
.setStencilCompareFunction(SamplerCompareFunction.NE);
|
||||
await highlightMaterialInstance.setStencilReferenceValue(1);
|
||||
@@ -197,10 +172,10 @@ class FFIAsset extends ThermionAsset {
|
||||
_highlight = highlightInstance;
|
||||
|
||||
await highlightMaterialInstance.setStencilReferenceValue(1);
|
||||
RenderableManager_setPriority(renderableManager, targetEntity, 0);
|
||||
final transformManager = Engine_getTransformManager(engine);
|
||||
RenderableManager_setPriority(app.renderableManager, targetEntity, 0);
|
||||
|
||||
TransformManager_setParent(
|
||||
transformManager, _highlight!.entity, entity, false);
|
||||
app.transformManager, _highlight!.entity, entity, false);
|
||||
}
|
||||
|
||||
var targetHighlightEntity = _highlight!.entity;
|
||||
@@ -210,35 +185,17 @@ class FFIAsset extends ThermionAsset {
|
||||
targetHighlightEntity = highlightChildEntities[entityIndex!];
|
||||
}
|
||||
|
||||
RenderableManager_setPriority(renderableManager, targetHighlightEntity, 7);
|
||||
RenderableManager_setPriority(
|
||||
app.renderableManager, targetHighlightEntity, 7);
|
||||
|
||||
SceneManager_addToScene(sceneManager, targetHighlightEntity);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future addToScene() async {
|
||||
SceneAsset_addToScene(pointer, SceneManager_getScene(sceneManager));
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future removeFromScene() async {
|
||||
SceneManager_removeFromScene(sceneManager, entity);
|
||||
for (final child in await getChildEntities()) {
|
||||
SceneManager_removeFromScene(sceneManager, child);
|
||||
}
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
FFIAsset? boundingBoxAsset;
|
||||
|
||||
Future<v64.Aabb3> getBoundingBox() async {
|
||||
final entities = <ThermionEntity>[];
|
||||
if (RenderableManager_isRenderable(renderableManager, entity)) {
|
||||
if (RenderableManager_isRenderable(app.renderableManager, entity)) {
|
||||
entities.add(entity);
|
||||
} else {
|
||||
entities.addAll(await getChildEntities());
|
||||
@@ -247,7 +204,7 @@ class FFIAsset extends ThermionAsset {
|
||||
var boundingBox = v64.Aabb3();
|
||||
|
||||
for (final entity in entities) {
|
||||
final aabb3 = SceneManager_getRenderableBoundingBox(sceneManager, entity);
|
||||
final aabb3 = RenderableManager_getAabb(app.renderableManager, entity);
|
||||
final entityBB = v64.Aabb3.centerAndHalfExtents(
|
||||
v64.Vector3(aabb3.centerX, aabb3.centerY, aabb3.centerZ),
|
||||
v64.Vector3(aabb3.halfExtentX, aabb3.halfExtentY, aabb3.halfExtentZ),
|
||||
@@ -263,7 +220,7 @@ class FFIAsset extends ThermionAsset {
|
||||
@override
|
||||
Future<void> setBoundingBoxVisibility(bool visible) async {
|
||||
if (boundingBoxAsset == null) {
|
||||
final boundingBox = await SceneAsset_getBoundingBox(pointer);
|
||||
final boundingBox = await SceneAsset_getBoundingBox(asset);
|
||||
|
||||
final min = [
|
||||
boundingBox.centerX - boundingBox.halfExtentX,
|
||||
@@ -323,10 +280,10 @@ class FFIAsset extends ThermionAsset {
|
||||
await withPointerCallback<TMaterialInstance>((cb) {
|
||||
final key = Struct.create<TMaterialKey>();
|
||||
MaterialProvider_createMaterialInstanceRenderThread(
|
||||
_unlitMaterialProvider, key.address, cb);
|
||||
app.ubershaderMaterialProvider, key.address, cb);
|
||||
});
|
||||
|
||||
final material = FFIMaterialInstance(materialInstancePtr, sceneManager);
|
||||
final material = FFIMaterialInstance(materialInstancePtr, app);
|
||||
await material.setParameterFloat4(
|
||||
"baseColorFactor", 1.0, 1.0, 0.0, 1.0); // Yellow wireframe
|
||||
|
||||
@@ -337,23 +294,25 @@ class FFIAsset extends ThermionAsset {
|
||||
primitiveType: PrimitiveType.LINES,
|
||||
);
|
||||
|
||||
boundingBoxAsset = await viewer.createGeometry(
|
||||
geometry,
|
||||
materialInstances: [material],
|
||||
keepData: false,
|
||||
) as FFIAsset;
|
||||
throw UnimplementedError();
|
||||
|
||||
await viewer.setCastShadows(boundingBoxAsset!.entity, false);
|
||||
await viewer.setReceiveShadows(boundingBoxAsset!.entity, false);
|
||||
// boundingBoxAsset = await viewer.createGeometry(
|
||||
// geometry,
|
||||
// materialInstances: [material],
|
||||
// keepData: false,
|
||||
// ) as FFIAsset;
|
||||
|
||||
TransformManager_setParent(Engine_getTransformManager(engine),
|
||||
await boundingBoxAsset!.setCastShadows(false);
|
||||
await boundingBoxAsset!.setReceiveShadows(false);
|
||||
|
||||
TransformManager_setParent(Engine_getTransformManager(app.engine),
|
||||
boundingBoxAsset!.entity, entity, false);
|
||||
}
|
||||
if (visible) {
|
||||
await boundingBoxAsset!.addToScene();
|
||||
} else {
|
||||
await boundingBoxAsset!.removeFromScene();
|
||||
}
|
||||
// if (visible) {
|
||||
// await boundingBoxAsset!.addToScene();
|
||||
// } else {
|
||||
// await boundingBoxAsset!.removeFromScene();
|
||||
// }
|
||||
}
|
||||
|
||||
///
|
||||
@@ -365,7 +324,25 @@ class FFIAsset extends ThermionAsset {
|
||||
final entities = <ThermionEntity>[entity, ...childEntities];
|
||||
for (final entity in entities) {
|
||||
RenderableManager_setMaterialInstanceAt(
|
||||
Engine_getRenderableManager(engine), entity, 0, instance.pointer);
|
||||
Engine_getRenderableManager(app.engine), entity, 0, instance.pointer);
|
||||
}
|
||||
}
|
||||
|
||||
Future setCastShadows(bool castShadows) async {
|
||||
RenderableManager_setCastShadows(
|
||||
app.renderableManager, this.entity, castShadows);
|
||||
for (final entity in await this.getChildEntities()) {
|
||||
RenderableManager_setCastShadows(
|
||||
app.renderableManager, entity, castShadows);
|
||||
}
|
||||
}
|
||||
|
||||
Future setReceiveShadows(bool receiveShadows) async {
|
||||
RenderableManager_setReceiveShadows(
|
||||
app.renderableManager, this.entity, receiveShadows);
|
||||
for (final entity in await this.getChildEntities()) {
|
||||
RenderableManager_setReceiveShadows(
|
||||
app.renderableManager, entity, receiveShadows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
final Pointer<TRenderableManager> renderableManager;
|
||||
final Pointer<TMaterialProvider> ubershaderMaterialProvider;
|
||||
final Pointer<TRenderTicker> renderTicker;
|
||||
final Pointer<TNameComponentManager> nameComponentManager;
|
||||
|
||||
FFIFilamentApp(
|
||||
this.engine,
|
||||
@@ -36,7 +37,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
this.lightManager,
|
||||
this.renderableManager,
|
||||
this.ubershaderMaterialProvider,
|
||||
this.renderTicker)
|
||||
this.renderTicker,
|
||||
this.nameComponentManager)
|
||||
: super(
|
||||
engine: engine,
|
||||
gltfAssetLoader: gltfAssetLoader,
|
||||
@@ -51,7 +53,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
if (_instance == null) {
|
||||
RenderLoop_destroy();
|
||||
RenderLoop_create();
|
||||
|
||||
|
||||
final engine = await withPointerCallback<TEngine>((cb) =>
|
||||
Engine_createRenderThread(
|
||||
TBackend.values[config.backend.index].index,
|
||||
@@ -76,7 +78,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
final renderableManager = Engine_getRenderableManager(engine);
|
||||
|
||||
final renderTicker = await withPointerCallback<TRenderTicker>(
|
||||
(cb) => RenderTicker_create());
|
||||
(cb) => RenderTicker_create(renderer));
|
||||
|
||||
final nameComponentManager = NameComponentManager_create();
|
||||
|
||||
_instance = FFIFilamentApp(
|
||||
engine,
|
||||
@@ -86,7 +90,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
transformManager,
|
||||
lightManager,
|
||||
renderableManager,
|
||||
ubershaderMaterialProvider);
|
||||
ubershaderMaterialProvider,
|
||||
renderTicker, nameComponentManager);
|
||||
}
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
class FFIMaterial extends Material {
|
||||
final Pointer<TEngine> engine;
|
||||
final Pointer<TSceneManager> sceneManager;
|
||||
final FFIFilamentApp app;
|
||||
final Pointer<TMaterial> pointer;
|
||||
|
||||
FFIMaterial(this.pointer, this.engine, this.sceneManager);
|
||||
FFIMaterial(this.pointer, this.app);
|
||||
|
||||
@override
|
||||
Future<MaterialInstance> createInstance() async {
|
||||
var ptr = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
Material_createInstanceRenderThread(pointer, cb);
|
||||
});
|
||||
return FFIMaterialInstance(ptr, sceneManager);
|
||||
return FFIMaterialInstance(ptr, this.app);
|
||||
}
|
||||
|
||||
Future dispose() async {
|
||||
Future destroy() async {
|
||||
await withVoidCallback((cb) {
|
||||
Engine_destroyMaterialRenderThread(engine, pointer, cb);
|
||||
Engine_destroyMaterialRenderThread(app.engine, pointer, cb);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ class FFIMaterial extends Material {
|
||||
|
||||
class FFIMaterialInstance extends MaterialInstance {
|
||||
final Pointer<TMaterialInstance> pointer;
|
||||
final Pointer<TSceneManager> sceneManager;
|
||||
final FFIFilamentApp app;
|
||||
|
||||
FFIMaterialInstance(this.pointer, this.sceneManager) {
|
||||
FFIMaterialInstance(this.pointer, this.app) {
|
||||
if (pointer == nullptr) {
|
||||
throw Exception("MaterialInstance not found");
|
||||
}
|
||||
@@ -169,10 +169,9 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
MaterialInstance_setStencilWriteMask(pointer, mask);
|
||||
}
|
||||
|
||||
Future dispose() async {
|
||||
Future destroy() async {
|
||||
await withVoidCallback((cb) {
|
||||
SceneManager_destroyMaterialInstanceRenderThread(
|
||||
sceneManager, pointer, cb);
|
||||
Engine_destroyMaterialInstanceRenderThread(app.engine, this.pointer, cb);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
|
||||
import 'callbacks.dart';
|
||||
import 'ffi_camera.dart';
|
||||
|
||||
|
||||
class FFIScene extends Scene {
|
||||
final Pointer<TScene> scene;
|
||||
@@ -12,8 +11,15 @@ class FFIScene extends Scene {
|
||||
|
||||
FFIRenderTarget? renderTarget;
|
||||
|
||||
FFIScene(this.scene, this.app) {
|
||||
|
||||
FFIScene(this.scene, this.app) {}
|
||||
|
||||
@override
|
||||
Future add(covariant FFIAsset asset) async {
|
||||
SceneAsset_addToScene(asset.asset, scene);
|
||||
}
|
||||
|
||||
@override
|
||||
Future remove(covariant FFIAsset asset) async {
|
||||
SceneAsset_removeFromScene(asset.asset, scene);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,14 +327,22 @@ external void LightManager_setDirection(
|
||||
double z,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Int Function(ffi.Pointer<TLightManager>, EntityId, ffi.Int)>(
|
||||
isLeaf: true)
|
||||
external int LightManager_createLight(
|
||||
@ffi.Native<ffi.Int Function(ffi.Pointer<TLightManager>, ffi.UnsignedInt)>(
|
||||
symbol: "LightManager_createLight", isLeaf: true)
|
||||
external int _LightManager_createLight(
|
||||
ffi.Pointer<TLightManager> tLightManager,
|
||||
int entity,
|
||||
int type,
|
||||
int tLightTtype,
|
||||
);
|
||||
|
||||
int LightManager_createLight(
|
||||
ffi.Pointer<TLightManager> tLightManager,
|
||||
TLightType tLightTtype,
|
||||
) =>
|
||||
_LightManager_createLight(
|
||||
tLightManager,
|
||||
tLightTtype.value,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TLightManager>, EntityId)>(
|
||||
isLeaf: true)
|
||||
external void LightManager_destroyLight(
|
||||
@@ -342,15 +350,12 @@ external void LightManager_destroyLight(
|
||||
int entity,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TLightManager>, EntityId, ffi.Double,
|
||||
ffi.Double, ffi.Double)>(isLeaf: true)
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TLightManager>, EntityId, ffi.Float)>(
|
||||
isLeaf: true)
|
||||
external void LightManager_setColor(
|
||||
ffi.Pointer<TLightManager> tLightManager,
|
||||
int entity,
|
||||
double r,
|
||||
double g,
|
||||
double b,
|
||||
double colorTemperature,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
@@ -995,6 +1000,9 @@ external void View_pick(
|
||||
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)
|
||||
@@ -1003,6 +1011,14 @@ external ffi.Pointer<ffi.Char> NameComponentManager_getName(
|
||||
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.Void Function(ffi.Pointer<TGizmo>, ffi.Uint32, ffi.Uint32,
|
||||
GizmoPickCallback)>(isLeaf: true)
|
||||
@@ -1067,6 +1083,12 @@ external void Scene_addEntity(
|
||||
int entityId,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, EntityId)>(isLeaf: true)
|
||||
external void Scene_removeEntity(
|
||||
ffi.Pointer<TScene> tScene,
|
||||
int entityId,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, ffi.Pointer<TSkybox>)>(
|
||||
isLeaf: true)
|
||||
external void Scene_setSkybox(
|
||||
@@ -1383,12 +1405,26 @@ external void Renderer_setFrameInterval(
|
||||
int interval,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TRenderTicker> Function(
|
||||
ffi.Pointer<TRenderer>, ffi.Pointer<TSceneManager>)>(isLeaf: true)
|
||||
@ffi.Native<ffi.Pointer<TRenderTicker> Function(ffi.Pointer<TRenderer>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TRenderTicker> RenderTicker_create(
|
||||
ffi.Pointer<TRenderer> tRenderer,
|
||||
ffi.Pointer<TSceneManager> tSceneManager,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
||||
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
||||
external void RenderTicker_addAnimationManager(
|
||||
ffi.Pointer<TRenderTicker> tRenderTicker,
|
||||
ffi.Pointer<TAnimationManager> tAnimationManager,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TRenderTicker>,
|
||||
ffi.Pointer<TAnimationManager>)>(isLeaf: true)
|
||||
external void RenderTicker_removeAnimationManager(
|
||||
ffi.Pointer<TRenderTicker> tRenderTicker,
|
||||
ffi.Pointer<TAnimationManager> tAnimationManager,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderTicker>, ffi.Uint64)>(
|
||||
@@ -1421,6 +1457,22 @@ external void RenderTicker_renderRenderThread(
|
||||
int frameTimeInNanos,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TEngine>,
|
||||
ffi.Pointer<TScene>,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TAnimationManager>)>>)>(isLeaf: true)
|
||||
external void AnimationManager_createRenderThread(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<TScene> tScene,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TAnimationManager>)>>
|
||||
onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Int,
|
||||
@@ -1549,6 +1601,15 @@ external void Engine_destroyMaterialRenderThread(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TMaterialInstance>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void Engine_destroyMaterialInstanceRenderThread(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<TMaterialInstance> tMaterialInstance,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TSkybox>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
@@ -3182,6 +3243,13 @@ external bool RenderableManager_getFogEnabled(
|
||||
int entityId,
|
||||
);
|
||||
|
||||
@ffi.Native<Aabb3 Function(ffi.Pointer<TRenderableManager>, EntityId)>(
|
||||
isLeaf: true)
|
||||
external Aabb3 RenderableManager_getAabb(
|
||||
ffi.Pointer<TRenderableManager> tRenderableManager,
|
||||
int entityId,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TEngine> Function(
|
||||
ffi.UnsignedInt,
|
||||
@@ -3324,6 +3392,14 @@ external void Engine_destroyMaterial(
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TEngine>, ffi.Pointer<TMaterialInstance>)>(isLeaf: true)
|
||||
external void Engine_destroyMaterialInstance(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<TMaterialInstance> tMaterialInstance,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||
external ffi.Pointer<TScene> Engine_createScene(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
@@ -3401,6 +3477,44 @@ external ffi.Pointer<TSceneAsset> SceneAsset_createGeometry(
|
||||
int materialInstanceCount,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TSceneAsset> Function(
|
||||
ffi.Pointer<TGltfAssetLoader>,
|
||||
ffi.Pointer<TGltfResourceLoader>,
|
||||
ffi.Pointer<TEngine>,
|
||||
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<TNameComponentManager> tNameComponentManager,
|
||||
ffi.Pointer<ffi.Uint8> data,
|
||||
int length,
|
||||
int numInstances,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TSceneAsset> Function(
|
||||
ffi.Pointer<TGltfAssetLoader>,
|
||||
ffi.Pointer<TGltfResourceLoader>,
|
||||
ffi.Pointer<TEngine>,
|
||||
ffi.Pointer<TNameComponentManager>,
|
||||
ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Size,
|
||||
ffi.Size)>(isLeaf: true)
|
||||
external ffi.Pointer<TSceneAsset> SceneAsset_loadGltf(
|
||||
ffi.Pointer<TGltfAssetLoader> tAssetLoader,
|
||||
ffi.Pointer<TGltfResourceLoader> tResourceLoader,
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<TNameComponentManager> tNameComponentManager,
|
||||
ffi.Pointer<ffi.Uint8> data,
|
||||
int length,
|
||||
int numInstances,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneAsset>, ffi.Pointer<TScene>)>(
|
||||
isLeaf: true)
|
||||
external void SceneAsset_addToScene(
|
||||
@@ -3408,6 +3522,13 @@ external void SceneAsset_addToScene(
|
||||
ffi.Pointer<TScene> tScene,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneAsset>, ffi.Pointer<TScene>)>(
|
||||
isLeaf: true)
|
||||
external void SceneAsset_removeFromScene(
|
||||
ffi.Pointer<TSceneAsset> tSceneAsset,
|
||||
ffi.Pointer<TScene> tScene,
|
||||
);
|
||||
|
||||
@ffi.Native<EntityId Function(ffi.Pointer<TSceneAsset>)>(isLeaf: true)
|
||||
external int SceneAsset_getEntity(
|
||||
ffi.Pointer<TSceneAsset> tSceneAsset,
|
||||
@@ -3465,6 +3586,12 @@ external Aabb3 SceneAsset_getBoundingBox(
|
||||
ffi.Pointer<TSceneAsset> asset,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TAnimationManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TAnimationManager> AnimationManager_create(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, EntityId)>(
|
||||
isLeaf: true)
|
||||
external void AnimationManager_addAnimationComponent(
|
||||
@@ -4131,6 +4258,26 @@ enum TTransparencyMode {
|
||||
};
|
||||
}
|
||||
|
||||
enum TLightType {
|
||||
LIGHT_TYPE_SUN(0),
|
||||
LIGHT_TYPE_DIRECTIONAL(1),
|
||||
LIGHT_TYPE_POINT(2),
|
||||
LIGHT_TYPE_FOCUSED_SPOT(3),
|
||||
LIGHT_TYPE_SPOT(4);
|
||||
|
||||
final int value;
|
||||
const TLightType(this.value);
|
||||
|
||||
static TLightType fromValue(int value) => switch (value) {
|
||||
0 => LIGHT_TYPE_SUN,
|
||||
1 => LIGHT_TYPE_DIRECTIONAL,
|
||||
2 => LIGHT_TYPE_POINT,
|
||||
3 => LIGHT_TYPE_FOCUSED_SPOT,
|
||||
4 => LIGHT_TYPE_SPOT,
|
||||
_ => throw ArgumentError("Unknown value for TLightType: $value"),
|
||||
};
|
||||
}
|
||||
|
||||
typedef EntityId = ffi.Int32;
|
||||
typedef DartEntityId = int;
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import 'callbacks.dart';
|
||||
import 'ffi_camera.dart';
|
||||
import 'ffi_view.dart';
|
||||
|
||||
const FILAMENT_ASSET_ERROR = 0;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -37,29 +39,30 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
|
||||
late final FFIFilamentApp app;
|
||||
late final FFIRenderTarget? renderTarget;
|
||||
late final Future<Uint8List> Function(String path) assetLoader;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
ThermionViewerFFI(this.app, {this.renderTarget}) {
|
||||
ThermionViewerFFI(this.assetLoader, this.app, {this.renderTarget}) {
|
||||
_onPickResultCallable =
|
||||
NativeCallable<PickCallbackFunction>.listener(_onPickResult);
|
||||
|
||||
_initialize();
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<RenderTarget> createRenderTarget(int width, int height,
|
||||
{covariant FFITexture? color, covariant FFITexture? depth}) async {
|
||||
final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
|
||||
RenderTarget_createRenderThread(app.engine, width, height,
|
||||
color?.pointer ?? nullptr, depth?.pointer ?? nullptr, cb);
|
||||
});
|
||||
// ///
|
||||
// ///
|
||||
// ///
|
||||
// Future<RenderTarget> createRenderTarget(int width, int height,
|
||||
// {covariant FFITexture? color, covariant FFITexture? depth}) async {
|
||||
// final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
|
||||
// RenderTarget_createRenderThread(app.engine, width, height,
|
||||
// color?.pointer ?? nullptr, depth?.pointer ?? nullptr, cb);
|
||||
// });
|
||||
|
||||
return FFIRenderTarget(renderTarget, app);
|
||||
}
|
||||
// return FFIRenderTarget(renderTarget, app);
|
||||
// }
|
||||
|
||||
///
|
||||
///
|
||||
@@ -95,6 +98,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
late final FFIView view;
|
||||
late final FFIScene scene;
|
||||
late final FFICamera camera;
|
||||
late final Pointer<TAnimationManager> animationManager;
|
||||
|
||||
Future _initialize() async {
|
||||
_logger.info("Initializing ThermionViewerFFI");
|
||||
@@ -111,6 +115,10 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
if (renderTarget != null) {
|
||||
await view.setRenderTarget(renderTarget);
|
||||
}
|
||||
animationManager = await withPointerCallback<TAnimationManager>((cb) =>
|
||||
AnimationManager_createRenderThread(app.engine, scene.scene, cb));
|
||||
|
||||
RenderTicker_addAnimationManager(app.renderTicker, animationManager);
|
||||
this._initialized.complete(true);
|
||||
}
|
||||
|
||||
@@ -136,79 +144,78 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
@override
|
||||
Future render() async {
|
||||
RenderTicker_renderRenderThread(app.renderTicker, 0);
|
||||
// Viewer_renderRenderThread(_viewer!, view.view, swapChain.swapChain);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<Uint8List> capture() async {
|
||||
final fence = await withPointerCallback<TFence>((cb) {
|
||||
Engine_createFenceRenderThread(app.engine!, cb);
|
||||
});
|
||||
// ///
|
||||
// ///
|
||||
// ///
|
||||
// @override
|
||||
// Future<Uint8List> capture() async {
|
||||
// final fence = await withPointerCallback<TFence>((cb) {
|
||||
// Engine_createFenceRenderThread(app.engine!, cb);
|
||||
// });
|
||||
|
||||
var pixelBuffers = <Uint8List>[];
|
||||
// var pixelBuffers = <Uint8List>[];
|
||||
|
||||
for (final entry in targets) {
|
||||
final view = entry.view as FFIView;
|
||||
var swapChain = entry.swapChain as FFISwapChain?;
|
||||
final renderTarget = entry.renderTarget as FFIRenderTarget?;
|
||||
final vp = await view.getViewport();
|
||||
final length = vp.width * vp.height * 4;
|
||||
// for (final entry in targets) {
|
||||
// final view = entry.view as FFIView;
|
||||
// var swapChain = entry.swapChain as FFISwapChain?;
|
||||
// final renderTarget = entry.renderTarget as FFIRenderTarget?;
|
||||
// final vp = await view.getViewport();
|
||||
// final length = vp.width * vp.height * 4;
|
||||
|
||||
await withBoolCallback((cb) {
|
||||
Renderer_beginFrameRenderThread(renderer,
|
||||
swapChain?.swapChain ?? Viewer_getSwapChainAt(_viewer!, 0), 0, cb);
|
||||
});
|
||||
// await withBoolCallback((cb) {
|
||||
// Renderer_beginFrameRenderThread(renderer,
|
||||
// swapChain?.swapChain ?? Viewer_getSwapChainAt(_viewer!, 0), 0, cb);
|
||||
// });
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Renderer_renderRenderThread(renderer, view.view, cb);
|
||||
});
|
||||
final out = Uint8List(length);
|
||||
await withVoidCallback((cb) {
|
||||
Renderer_readPixelsRenderThread(
|
||||
renderer,
|
||||
view.view,
|
||||
renderTarget!.renderTarget,
|
||||
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||
TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||
out.address,
|
||||
cb);
|
||||
});
|
||||
// await withVoidCallback((cb) {
|
||||
// Renderer_renderRenderThread(renderer, view.view, cb);
|
||||
// });
|
||||
// final out = Uint8List(length);
|
||||
// await withVoidCallback((cb) {
|
||||
// Renderer_readPixelsRenderThread(
|
||||
// renderer,
|
||||
// view.view,
|
||||
// renderTarget!.renderTarget,
|
||||
// TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||
// TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||
// out.address,
|
||||
// cb);
|
||||
// });
|
||||
|
||||
pixelBuffers.add(out);
|
||||
}
|
||||
// pixelBuffers.add(out);
|
||||
// }
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Renderer_endFrameRenderThread(renderer, cb);
|
||||
});
|
||||
// await withVoidCallback((cb) {
|
||||
// Renderer_endFrameRenderThread(renderer, cb);
|
||||
// });
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Engine_flushAndWaitRenderThead(app.engine!, cb);
|
||||
});
|
||||
// await withVoidCallback((cb) {
|
||||
// Engine_flushAndWaitRenderThead(app.engine!, cb);
|
||||
// });
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Engine_destroyFenceRenderThread(app.engine!, fence, cb);
|
||||
});
|
||||
// await withVoidCallback((cb) {
|
||||
// Engine_destroyFenceRenderThread(app.engine!, fence, cb);
|
||||
// });
|
||||
|
||||
// await withVoidCallback((cb) {
|
||||
// if (renderTarget != null) {
|
||||
// Viewer_captureRenderTargetRenderThread(
|
||||
// _viewer!,
|
||||
// view!.view,
|
||||
// swapChain!.swapChain,
|
||||
// renderTarget.renderTarget,
|
||||
// out.address,
|
||||
// useFence,
|
||||
// cb);
|
||||
// } else {
|
||||
// Viewer_captureRenderThread(_viewer!, view!.view, swapChain!.swapChain,
|
||||
// out.address, useFence, cb);
|
||||
// }
|
||||
// });
|
||||
return pixelBuffers;
|
||||
}
|
||||
// // await withVoidCallback((cb) {
|
||||
// // if (renderTarget != null) {
|
||||
// // Viewer_captureRenderTargetRenderThread(
|
||||
// // _viewer!,
|
||||
// // view!.view,
|
||||
// // swapChain!.swapChain,
|
||||
// // renderTarget.renderTarget,
|
||||
// // out.address,
|
||||
// // useFence,
|
||||
// // cb);
|
||||
// // } else {
|
||||
// // Viewer_captureRenderThread(_viewer!, view!.view, swapChain!.swapChain,
|
||||
// // out.address, useFence, cb);
|
||||
// // }
|
||||
// // });
|
||||
// return pixelBuffers;
|
||||
// }
|
||||
|
||||
double _msPerFrame = 1000.0 / 60.0;
|
||||
|
||||
@@ -225,7 +232,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
@override
|
||||
Future setFrameRate(int framerate) async {
|
||||
_msPerFrame = 1000.0 / framerate;
|
||||
set_frame_interval_render_thread(_viewer!, _msPerFrame);
|
||||
}
|
||||
|
||||
final _onDispose = <Future Function()>[];
|
||||
@@ -238,20 +244,14 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future dispose() async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("Viewer has already been disposed.");
|
||||
}
|
||||
_disposing = true;
|
||||
await setRendering(false);
|
||||
await destroyAssets();
|
||||
for (final mInstance in _materialInstances) {
|
||||
await mInstance.dispose();
|
||||
await mInstance.destroy();
|
||||
}
|
||||
await destroyLights();
|
||||
|
||||
_sceneManager = null;
|
||||
_viewer = null;
|
||||
|
||||
for (final callback in _onDispose) {
|
||||
await callback.call();
|
||||
}
|
||||
@@ -310,34 +310,39 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future loadSkybox(String skyboxPath) async {
|
||||
final pathPtr = skyboxPath.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||
var data = await _loadAsset(skyboxPath);
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Viewer_loadSkyboxRenderThread(_viewer!, pathPtr, cb);
|
||||
skybox = await withPointerCallback<TSkybox>((cb) {
|
||||
Engine_buildSkyboxRenderThread(
|
||||
app.engine, data.address, data.length, cb, nullptr);
|
||||
});
|
||||
|
||||
allocator.free(pathPtr);
|
||||
Scene_setSkybox(scene.scene, skybox!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future createIbl(double r, double g, double b, double intensity) async {
|
||||
create_ibl(_viewer!, r, g, b, intensity);
|
||||
Future<Uint8List> _loadAsset(String path) async {
|
||||
if (path.startsWith("file://")) {
|
||||
return File(path.replaceAll("file://", "")).readAsBytesSync();
|
||||
}
|
||||
if (path.startsWith("asset://")) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Pointer<TIndirectLight>? indirectLight;
|
||||
Pointer<TSkybox>? skybox;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
|
||||
final pathPtr =
|
||||
lightingPath.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Viewer_loadIblRenderThread(_viewer!, pathPtr, intensity, cb);
|
||||
var data = await _loadAsset(lightingPath);
|
||||
indirectLight = await withPointerCallback<TIndirectLight>((cb) {
|
||||
Engine_buildIndirectLightRenderThread(
|
||||
app.engine, data.address, data.length, intensity, cb, nullptr);
|
||||
});
|
||||
Scene_setIndirectLight(scene.scene, indirectLight!);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -345,12 +350,10 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future rotateIbl(Matrix3 rotationMatrix) async {
|
||||
var floatPtr = allocator<Float>(9);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
floatPtr[i] = rotationMatrix.storage[i];
|
||||
if (indirectLight == null) {
|
||||
throw Exception("No IBL loaded");
|
||||
}
|
||||
rotate_ibl(_viewer!, floatPtr);
|
||||
allocator.free(floatPtr);
|
||||
IndirectLight_setRotation(indirectLight!, rotationMatrix.storage.address);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -358,9 +361,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future removeSkybox() async {
|
||||
await withVoidCallback((cb) {
|
||||
Viewer_removeSkyboxRenderThread(_viewer!, cb);
|
||||
});
|
||||
if (skybox != null) {
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_destroySkyboxRenderThread(app.engine, skybox!, cb));
|
||||
skybox = null;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
@@ -368,9 +373,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future removeIbl() async {
|
||||
await withVoidCallback((cb) {
|
||||
Viewer_removeIblRenderThread(_viewer!, cb);
|
||||
});
|
||||
if (indirectLight != null) {
|
||||
await withVoidCallback((cb) => Engine_destroyIndirectLightRenderThread(
|
||||
app.engine, indirectLight!, cb));
|
||||
indirectLight = null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -408,35 +415,38 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
return addDirectLight(directLight);
|
||||
}
|
||||
|
||||
final _lights = <ThermionEntity>{};
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
|
||||
var entity = await withIntCallback((cb) {
|
||||
SceneManager_addLightRenderThread(
|
||||
_sceneManager!,
|
||||
directLight.type.index,
|
||||
directLight.color,
|
||||
directLight.intensity,
|
||||
directLight.position.x,
|
||||
directLight.position.y,
|
||||
directLight.position.z,
|
||||
directLight.direction.x,
|
||||
directLight.direction.y,
|
||||
directLight.direction.z,
|
||||
directLight.falloffRadius,
|
||||
directLight.spotLightConeInner,
|
||||
directLight.spotLightConeOuter,
|
||||
directLight.sunAngularRadius,
|
||||
directLight.sunHaloSize,
|
||||
directLight.sunHaloFallof,
|
||||
directLight.castShadows,
|
||||
cb);
|
||||
});
|
||||
var entity = LightManager_createLight(
|
||||
app.lightManager, TLightType.values[directLight.type.index]);
|
||||
if (entity == FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("Failed to add light to scene");
|
||||
}
|
||||
LightManager_setColor(app.lightManager, entity, directLight.color);
|
||||
LightManager_setIntensity(app.lightManager, entity, directLight.intensity);
|
||||
LightManager_setPosition(app.lightManager, entity, directLight.position.x,
|
||||
directLight.position.y, directLight.position.z);
|
||||
LightManager_setDirection(app.lightManager, entity, directLight.direction.x,
|
||||
directLight.direction.y, directLight.direction.z);
|
||||
LightManager_setFalloff(
|
||||
app.lightManager, entity, directLight.falloffRadius);
|
||||
LightManager_setSpotLightCone(app.lightManager, entity,
|
||||
directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||
// LightManager_setSunAngularRadius(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||
// LightManager_setSunHaloSize(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||
// LightManager_setSunHaloFalloff(app.lightManager, entity, directLight.spotLightConeInner, directLight.spotLightConeOuter);
|
||||
LightManager_setShadowCaster(
|
||||
app.lightManager, entity, directLight.castShadows);
|
||||
|
||||
Scene_addEntity(scene.scene, entity);
|
||||
|
||||
_lights.add(entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -445,9 +455,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future removeLight(ThermionEntity entity) async {
|
||||
await withVoidCallback((cb) {
|
||||
SceneManager_removeLightRenderThread(_sceneManager!, entity, cb);
|
||||
});
|
||||
Scene_removeEntity(scene.scene, entity);
|
||||
LightManager_destroyLight(app.lightManager, entity);
|
||||
_lights.remove(entity);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -455,34 +465,23 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future destroyLights() async {
|
||||
await withVoidCallback((cb) {
|
||||
SceneManager_destroyLightsRenderThread(_sceneManager!, cb);
|
||||
});
|
||||
for (final light in _lights) {
|
||||
await removeLight(light);
|
||||
}
|
||||
}
|
||||
|
||||
final _assets = <ThermionAsset>{};
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<ThermionAsset> loadGlb(String path,
|
||||
{bool unlit = false, int numInstances = 1, bool keepData = false}) async {
|
||||
if (unlit) {
|
||||
throw Exception("Not yet implemented");
|
||||
}
|
||||
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||
var asset = await withPointerCallback<TSceneAsset>((callback) =>
|
||||
SceneManager_loadGlbRenderThread(
|
||||
_sceneManager!, pathPtr, numInstances, keepData, callback));
|
||||
{int numInstances = 1, bool keepData = false}) async {
|
||||
final data = await assetLoader(path);
|
||||
|
||||
allocator.free(pathPtr);
|
||||
if (asset == nullptr) {
|
||||
throw Exception("An error occurred loading the asset at $path");
|
||||
}
|
||||
|
||||
var thermionAsset = FFIAsset(
|
||||
asset, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
|
||||
|
||||
return thermionAsset;
|
||||
return loadGlbFromBuffer(data,
|
||||
numInstances: numInstances, keepData: keepData);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -490,37 +489,29 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future<ThermionAsset> loadGlbFromBuffer(Uint8List data,
|
||||
{bool unlit = false,
|
||||
int numInstances = 1,
|
||||
{int numInstances = 1,
|
||||
bool keepData = false,
|
||||
int priority = 4,
|
||||
int layer = 0,
|
||||
bool loadResourcesAsync = false}) async {
|
||||
if (unlit) {
|
||||
throw Exception("Not yet implemented");
|
||||
var asset = SceneAsset_loadGlb(
|
||||
app.gltfAssetLoader,
|
||||
app.gltfResourceLoader,
|
||||
app.engine,
|
||||
app.nameComponentManager,
|
||||
data.address,
|
||||
data.length,
|
||||
numInstances);
|
||||
|
||||
if (asset == nullptr) {
|
||||
throw Exception("An error occurred loading the asset");
|
||||
}
|
||||
|
||||
if (layer < 0 || layer > 6) {
|
||||
throw Exception("Layer must be between 0 and 6");
|
||||
}
|
||||
var thermionAsset = FFIAsset(asset, app);
|
||||
|
||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) =>
|
||||
SceneManager_loadGlbFromBufferRenderThread(
|
||||
_sceneManager!,
|
||||
data.address,
|
||||
data.length,
|
||||
numInstances,
|
||||
keepData,
|
||||
priority,
|
||||
layer,
|
||||
loadResourcesAsync,
|
||||
callback));
|
||||
_assets.add(thermionAsset);
|
||||
|
||||
if (assetPtr == nullptr) {
|
||||
throw Exception("An error occurred loading GLB from buffer");
|
||||
}
|
||||
return FFIAsset(
|
||||
assetPtr, _sceneManager!, app.engine!, _unlitMaterialProvider!, this);
|
||||
return thermionAsset;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1694,8 +1685,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future<v64.Aabb3> getRenderableBoundingBox(ThermionEntity entityId) async {
|
||||
final result =
|
||||
SceneManager_getRenderableBoundingBox(_sceneManager!, entityId);
|
||||
final result = RenderableManager_getAabb(app.renderableManager, entityId);
|
||||
return v64.Aabb3.centerAndHalfExtents(
|
||||
Vector3(result.centerX, result.centerY, result.centerZ),
|
||||
Vector3(result.halfExtentX, result.halfExtentY, result.halfExtentZ));
|
||||
@@ -1706,10 +1696,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future<v64.Aabb2> getViewportBoundingBox(ThermionEntity entityId) async {
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
final result = get_bounding_box(_sceneManager!, view.view, entityId);
|
||||
return v64.Aabb2.minMax(v64.Vector2(result.minX, result.minY),
|
||||
v64.Vector2(result.maxX, result.maxY));
|
||||
throw UnimplementedError();
|
||||
// final view = (await getViewAt(0)) as FFIView;
|
||||
// final result = get_bounding_box(_sceneManager!, view.view, entityId);
|
||||
// return v64.Aabb2.minMax(v64.Vector2(result.minX, result.minY),
|
||||
// v64.Vector2(result.maxX, result.maxY));
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -8,7 +8,7 @@ export 'gltf.dart';
|
||||
|
||||
export 'light_options.dart';
|
||||
|
||||
// repre handle that can be safely passed back to the rendering layer to manipulate an Entity
|
||||
// handle manipulate an Entity
|
||||
typedef ThermionEntity = int;
|
||||
|
||||
abstract class ThermionAsset {
|
||||
@@ -66,15 +66,8 @@ abstract class ThermionAsset {
|
||||
///
|
||||
Future<List<ThermionAsset>> getInstances();
|
||||
|
||||
///
|
||||
/// Adds all entities (renderable, lights and cameras) under [asset] to the scene.
|
||||
///
|
||||
Future addToScene();
|
||||
|
||||
///
|
||||
/// Removes all entities (renderable, lights and cameras) under [asset] from the scene.
|
||||
///
|
||||
Future removeFromScene();
|
||||
Future setCastShadows(bool castShadows);
|
||||
Future setReceiveShadows(bool castShadows);
|
||||
}
|
||||
|
||||
enum Axis {
|
||||
|
||||
@@ -97,7 +97,7 @@ enum TransparencyMode {
|
||||
abstract class Material {
|
||||
Future<MaterialInstance> createInstance();
|
||||
Future<bool> hasParameter(String propertyName);
|
||||
Future dispose();
|
||||
Future destroy();
|
||||
}
|
||||
|
||||
abstract class MaterialInstance {
|
||||
@@ -146,5 +146,5 @@ abstract class MaterialInstance {
|
||||
|
||||
Future setTransparencyMode(TransparencyMode mode);
|
||||
|
||||
Future dispose();
|
||||
Future destroy();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:thermion_dart/src/viewer/src/thermion_viewer_base.dart';
|
||||
|
||||
abstract class Scene {
|
||||
|
||||
Future add(covariant ThermionAsset asset);
|
||||
Future remove(covariant ThermionAsset asset);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
///
|
||||
/// A high-level interface for interacting with a 3D scene.
|
||||
/// This broadly maps to a single scene/view
|
||||
///
|
||||
///
|
||||
abstract class ThermionViewer {
|
||||
|
||||
///
|
||||
@@ -40,8 +40,9 @@ abstract class ThermionViewer {
|
||||
/// Render a single frame and return the captured image as a pixel buffer.
|
||||
///
|
||||
Future<List<Uint8List>> capture(
|
||||
covariant List<({View view, SwapChain? swapChain, RenderTarget? renderTarget})> targets);
|
||||
|
||||
covariant List<
|
||||
({View view, SwapChain? swapChain, RenderTarget? renderTarget})>
|
||||
targets);
|
||||
|
||||
///
|
||||
///
|
||||
@@ -108,12 +109,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future loadIbl(String lightingPath, {double intensity = 30000});
|
||||
|
||||
///
|
||||
/// Creates a indirect light with the given color.
|
||||
/// Only one indirect light can be active at any given time; if an indirect light has already been loaded, it will be replaced.
|
||||
///
|
||||
Future createIbl(double r, double g, double b, double intensity);
|
||||
|
||||
///
|
||||
/// Rotates the IBL & skybox.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user