refactor!: refactor to support multiple Views/Render Targets
This commit is contained in:
@@ -3,10 +3,14 @@ headers:
|
||||
entry-points:
|
||||
- '../native/include/ThermionDartRenderThreadApi.h'
|
||||
- '../native/include/ThermionDartApi.h'
|
||||
- '../native/include/TView.h'
|
||||
- '../native/include/TGizmo.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
include-directives:
|
||||
- '../native/include/ThermionDartRenderThreadApi.h'
|
||||
- '../native/include/ThermionDartApi.h'
|
||||
- '../native/include/TView.h'
|
||||
- '../native/include/TGizmo.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
- '../native/include/APIBoundaryTypes.h'
|
||||
ffi-native:
|
||||
|
||||
@@ -45,14 +45,6 @@ external void Viewer_destroyRenderTarget(
|
||||
ffi.Pointer<TRenderTarget> tRenderTarget,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>, ffi.Pointer<TRenderTarget>)>(isLeaf: true)
|
||||
external void Viewer_setRenderTarget(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TRenderTarget> tRenderTarget,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TSwapChain> Function(ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<ffi.Void>, ffi.Uint32, ffi.Uint32)>(isLeaf: true)
|
||||
@@ -73,6 +65,7 @@ external void Viewer_destroySwapChain(
|
||||
@ffi.Native<
|
||||
ffi.Bool Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Pointer<TSwapChain>,
|
||||
ffi.Uint64,
|
||||
ffi.Pointer<ffi.Void>,
|
||||
@@ -83,6 +76,7 @@ external void Viewer_destroySwapChain(
|
||||
ffi.Pointer<ffi.Void>)>(isLeaf: true)
|
||||
external bool Viewer_render(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> view,
|
||||
ffi.Pointer<TSwapChain> swapChain,
|
||||
int frameTimeInNanos,
|
||||
ffi.Pointer<ffi.Void> pixelBuffer,
|
||||
@@ -97,11 +91,13 @@ external bool Viewer_render(
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Pointer<TSwapChain>,
|
||||
ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void Viewer_capture(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> view,
|
||||
ffi.Pointer<TSwapChain> swapChain,
|
||||
ffi.Pointer<ffi.Uint8> pixelBuffer,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||
@@ -110,18 +106,39 @@ external void Viewer_capture(
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Pointer<TSwapChain>,
|
||||
ffi.Pointer<TRenderTarget>,
|
||||
ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void Viewer_captureRenderTarget(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> view,
|
||||
ffi.Pointer<TSwapChain> swapChain,
|
||||
ffi.Pointer<TRenderTarget> renderTarget,
|
||||
ffi.Pointer<ffi.Uint8> pixelBuffer,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TView> Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external ffi.Pointer<TView> Viewer_createView(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TView> Function(ffi.Pointer<TViewer>, ffi.Int)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TView> Viewer_getViewAt(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int index,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<TView>)>(
|
||||
isLeaf: true)
|
||||
external void Viewer_setMainCamera(
|
||||
ffi.Pointer<TViewer> tViewer,
|
||||
ffi.Pointer<TView> tView,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TEngine> Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external ffi.Pointer<TEngine> Viewer_getEngine(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
@@ -177,12 +194,6 @@ external void set_background_color(
|
||||
double a,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Int)>(isLeaf: true)
|
||||
external void set_tone_mapping(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int toneMapping,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float)>(isLeaf: true)
|
||||
external void set_bloom(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
@@ -360,25 +371,11 @@ external void get_instances(
|
||||
ffi.Pointer<EntityId> out,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external void set_main_camera(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<EntityId Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external int get_main_camera(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Bool Function(
|
||||
ffi.Pointer<TViewer>, EntityId, ffi.Pointer<ffi.Char>)>(isLeaf: true)
|
||||
external bool set_camera(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int entity,
|
||||
ffi.Pointer<ffi.Char> nodeName,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Bool)>(isLeaf: true)
|
||||
external void set_view_frustum_culling(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
@@ -391,57 +388,6 @@ external void set_frame_interval(
|
||||
double interval,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Uint32, ffi.Uint32)>(
|
||||
isLeaf: true)
|
||||
external void update_viewport(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int width,
|
||||
int height,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external void scroll_begin(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>, ffi.Float, ffi.Float, ffi.Float)>(isLeaf: true)
|
||||
external void scroll_update(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external void scroll_end(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>, ffi.Float, ffi.Float, ffi.Bool)>(isLeaf: true)
|
||||
external void grab_begin(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
double x,
|
||||
double y,
|
||||
bool pan,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float, ffi.Float)>(
|
||||
isLeaf: true)
|
||||
external void grab_update(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
double x,
|
||||
double y,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external void grab_end(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TSceneManager>, EntityId,
|
||||
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Float>, ffi.Int)>(isLeaf: true)
|
||||
@@ -699,6 +645,29 @@ external void SceneManager_queueTransformUpdates(
|
||||
int numEntities,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TCamera> Function(ffi.Pointer<TSceneManager>, EntityId,
|
||||
ffi.Pointer<ffi.Char>)>(isLeaf: true)
|
||||
external ffi.Pointer<TCamera> SceneManager_findCameraByName(
|
||||
ffi.Pointer<TSceneManager> tSceneManager,
|
||||
int entity,
|
||||
ffi.Pointer<ffi.Char> name,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneManager>, EntityId, ffi.Int)>(
|
||||
isLeaf: true)
|
||||
external void SceneManager_setVisibilityLayer(
|
||||
ffi.Pointer<TSceneManager> tSceneManager,
|
||||
int entity,
|
||||
int layer,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TGizmo> Function(ffi.Pointer<TSceneManager>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TGizmo> SceneManager_getGizmo(
|
||||
ffi.Pointer<TSceneManager> tSceneManager,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId)>(
|
||||
isLeaf: true)
|
||||
external bool update_bone_matrices(
|
||||
@@ -778,10 +747,11 @@ external void queue_relative_position_update_world_axis(
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TSceneManager>, EntityId, ffi.Float,
|
||||
ffi.Float)>(isLeaf: true)
|
||||
ffi.Void Function(ffi.Pointer<TSceneManager>, ffi.Pointer<TView>, EntityId,
|
||||
ffi.Float, ffi.Float)>(isLeaf: true)
|
||||
external void queue_position_update_from_viewport_coords(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<TView> view,
|
||||
int entity,
|
||||
double viewportX,
|
||||
double viewportY,
|
||||
@@ -942,17 +912,6 @@ external void set_camera_focus_distance(
|
||||
double focusDistance,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TViewer>, _ManipulatorMode, ffi.Double,
|
||||
ffi.Double, ffi.Double)>(isLeaf: true)
|
||||
external void set_camera_manipulator_options(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int mode,
|
||||
double orbitSpeedX,
|
||||
double orbitSpeedY,
|
||||
double zoomSpeed,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TCamera>, double4x4, ffi.Double, ffi.Double)>(isLeaf: true)
|
||||
@@ -1005,14 +964,6 @@ external void SceneManager_destroyCamera(
|
||||
ffi.Pointer<TCamera> camera,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>, ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||
external void SceneManager_setCamera(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<TCamera> camera,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Size Function(ffi.Pointer<TSceneManager>)>(isLeaf: true)
|
||||
external int SceneManager_getCameraCount(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
@@ -1026,12 +977,6 @@ external ffi.Pointer<TCamera> SceneManager_getCameraAt(
|
||||
int index,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TSceneManager>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TCamera> SceneManager_getActiveCamera(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Int Function(ffi.Pointer<TSceneManager>, EntityId,
|
||||
ffi.Pointer<ffi.Char>)>(isLeaf: true)
|
||||
@@ -1050,45 +995,10 @@ external int reveal_mesh(
|
||||
ffi.Pointer<ffi.Char> meshName,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Bool)>(isLeaf: true)
|
||||
external void set_post_processing(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
bool enabled,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Bool)>(isLeaf: true)
|
||||
external void set_shadows_enabled(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
bool enabled,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Int)>(isLeaf: true)
|
||||
external void set_shadow_type(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int shadowType,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float, ffi.Float)>(
|
||||
isLeaf: true)
|
||||
external void set_soft_shadow_options(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
double penumbraScale,
|
||||
double penumbraRatioScale,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>, ffi.Bool, ffi.Bool, ffi.Bool)>(isLeaf: true)
|
||||
external void set_antialiasing(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
bool msaa,
|
||||
bool fxaa,
|
||||
bool taa,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<
|
||||
@@ -1097,6 +1007,7 @@ external void set_antialiasing(
|
||||
EntityId entityId, ffi.Int x, ffi.Int y)>>)>(isLeaf: true)
|
||||
external void filament_pick(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> tView,
|
||||
int x,
|
||||
int y,
|
||||
ffi.Pointer<
|
||||
@@ -1273,15 +1184,19 @@ external void get_gizmo(
|
||||
ffi.Pointer<EntityId> out,
|
||||
);
|
||||
|
||||
@ffi.Native<Aabb2 Function(ffi.Pointer<TSceneManager>, EntityId)>(isLeaf: true)
|
||||
@ffi.Native<
|
||||
Aabb2 Function(
|
||||
ffi.Pointer<TSceneManager>, ffi.Pointer<TView>, EntityId)>(isLeaf: true)
|
||||
external Aabb2 get_bounding_box(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<TView> view,
|
||||
int entity,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<TView>,
|
||||
EntityId,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
@@ -1289,6 +1204,7 @@ external Aabb2 get_bounding_box(
|
||||
ffi.Pointer<ffi.Float>)>(isLeaf: true)
|
||||
external void get_bounding_box_to_out(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<TView> view,
|
||||
int entity,
|
||||
ffi.Pointer<ffi.Float> minX,
|
||||
ffi.Pointer<ffi.Float> minY,
|
||||
@@ -1296,41 +1212,6 @@ external void get_bounding_box_to_out(
|
||||
ffi.Pointer<ffi.Float> maxY,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneManager>, ffi.Int, ffi.Bool)>(
|
||||
isLeaf: true)
|
||||
external void set_layer_visibility(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
int layer,
|
||||
bool visible,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneManager>, EntityId, ffi.Int)>(
|
||||
isLeaf: true)
|
||||
external void set_visibility_layer(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
int entity,
|
||||
int layer,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
EntityId entityId, ffi.Int x, ffi.Int y)>>)>(isLeaf: true)
|
||||
external void pick_gizmo(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
int x,
|
||||
int y,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y)>>
|
||||
callback,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneManager>, ffi.Bool)>(
|
||||
isLeaf: true)
|
||||
external void set_gizmo_visibility(
|
||||
@@ -1537,21 +1418,25 @@ external void Viewer_destroySwapChainRenderThread(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<TSwapChain>)>(
|
||||
isLeaf: true)
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<TView>,
|
||||
ffi.Pointer<TSwapChain>)>(isLeaf: true)
|
||||
external void Viewer_renderRenderThread(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> view,
|
||||
ffi.Pointer<TSwapChain> swapChain,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Pointer<TSwapChain>,
|
||||
ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void Viewer_captureRenderThread(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> view,
|
||||
ffi.Pointer<TSwapChain> swapChain,
|
||||
ffi.Pointer<ffi.Uint8> out,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||
@@ -1560,12 +1445,14 @@ external void Viewer_captureRenderThread(
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Pointer<TSwapChain>,
|
||||
ffi.Pointer<TRenderTarget>,
|
||||
ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void Viewer_captureRenderTargetRenderThread(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> view,
|
||||
ffi.Pointer<TSwapChain> swapChain,
|
||||
ffi.Pointer<TRenderTarget> renderTarget,
|
||||
ffi.Pointer<ffi.Uint8> out,
|
||||
@@ -1749,17 +1636,6 @@ external void clear_entities_render_thread(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TViewer>, EntityId, ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>(
|
||||
isLeaf: true)
|
||||
external void set_camera_render_thread(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
int asset,
|
||||
ffi.Pointer<ffi.Char> nodeName,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TSceneManager>, EntityId,
|
||||
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Float>, ffi.Int)>(isLeaf: true)
|
||||
@@ -1956,6 +1832,119 @@ external void unproject_texture_render_thread(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||
);
|
||||
|
||||
@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.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
|
||||
isLeaf: true)
|
||||
external void View_updateViewport(
|
||||
ffi.Pointer<TView> tView,
|
||||
int width,
|
||||
int height,
|
||||
);
|
||||
|
||||
@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.Float)>(isLeaf: true)
|
||||
external void View_setBloom(
|
||||
ffi.Pointer<TView> tView,
|
||||
double strength,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TView>, ffi.Pointer<TEngine>, ffi.Int)>(isLeaf: true)
|
||||
external void View_setToneMapping(
|
||||
ffi.Pointer<TView> tView,
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
int toneMapping,
|
||||
);
|
||||
|
||||
@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<TCamera> Function(ffi.Pointer<TView>)>(isLeaf: true)
|
||||
external ffi.Pointer<TCamera> View_getCamera(
|
||||
ffi.Pointer<TView> tView,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TGizmo>,
|
||||
ffi.Pointer<TView>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
EntityId entityId, ffi.Int x, ffi.Int y)>>)>(isLeaf: true)
|
||||
external void Gizmo_pick(
|
||||
ffi.Pointer<TGizmo> tGizmo,
|
||||
ffi.Pointer<TView> tView,
|
||||
int x,
|
||||
int y,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y)>>
|
||||
callback,
|
||||
);
|
||||
|
||||
final class TCamera extends ffi.Opaque {}
|
||||
|
||||
final class TMaterialInstance extends ffi.Opaque {}
|
||||
@@ -1972,6 +1961,10 @@ final class TRenderTarget extends ffi.Opaque {}
|
||||
|
||||
final class TSwapChain extends ffi.Opaque {}
|
||||
|
||||
final class TView extends ffi.Opaque {}
|
||||
|
||||
final class TGizmo extends ffi.Opaque {}
|
||||
|
||||
final class TMaterialKey extends ffi.Struct {
|
||||
@ffi.Bool()
|
||||
external bool doubleSided;
|
||||
@@ -2197,8 +2190,6 @@ typedef DartLoadFilamentResourceIntoOutPointerFunction = void Function(
|
||||
/// - setting up a render loop
|
||||
typedef EntityId = ffi.Int32;
|
||||
typedef DartEntityId = int;
|
||||
typedef _ManipulatorMode = ffi.Int32;
|
||||
typedef Dart_ManipulatorMode = int;
|
||||
typedef FilamentRenderCallback
|
||||
= ffi.Pointer<ffi.NativeFunction<FilamentRenderCallbackFunction>>;
|
||||
typedef FilamentRenderCallbackFunction = ffi.Void Function(
|
||||
|
||||
@@ -10,6 +10,7 @@ import '../../../../entities/gizmo.dart';
|
||||
import '../../../../utils/matrix.dart';
|
||||
import '../../events.dart';
|
||||
import '../../shared_types/camera.dart';
|
||||
import '../../shared_types/view.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
@@ -111,12 +112,28 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
Future setRenderTarget(FFIRenderTarget renderTarget) async {
|
||||
Viewer_setRenderTarget(_viewer!, renderTarget.renderTarget);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
View_setRenderTarget(view.view, renderTarget.renderTarget);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<View> createView() async {
|
||||
var view = Viewer_createView(_viewer!);
|
||||
if (view == nullptr) {
|
||||
throw Exception("Failed to create view");
|
||||
}
|
||||
return FFIView(view, _viewer!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future updateViewportAndCameraProjection(double width, double height) async {
|
||||
viewportDimensions = (width * pixelRatio, height * pixelRatio);
|
||||
update_viewport(_viewer!, width.toInt(), height.toInt());
|
||||
var mainView = FFIView(Viewer_getViewAt(_viewer!, 0), _viewer!);
|
||||
mainView.updateViewport(width.toInt(), height.toInt());
|
||||
|
||||
final cameraCount = await getCameraCount();
|
||||
|
||||
@@ -176,8 +193,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
|
||||
_sceneManager = Viewer_getSceneManager(_viewer!);
|
||||
|
||||
await setCameraManipulatorOptions(zoomSpeed: 1.0);
|
||||
|
||||
final gizmoEntities = allocator<Int32>(4);
|
||||
get_gizmo(_sceneManager!, gizmoEntities);
|
||||
_gizmo = Gizmo(gizmoEntities[0], gizmoEntities[1], gizmoEntities[2],
|
||||
@@ -210,7 +225,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future render(FFISwapChain swapChain) async {
|
||||
Viewer_renderRenderThread(_viewer!, swapChain.swapChain);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
Viewer_renderRenderThread(_viewer!, view.view, swapChain.swapChain);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -223,13 +239,14 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
this.viewportDimensions.$2.toInt() *
|
||||
4;
|
||||
final out = Uint8List(length);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
await withVoidCallback((cb) {
|
||||
if (renderTarget != null) {
|
||||
Viewer_captureRenderTargetRenderThread(
|
||||
_viewer!, swapChain.swapChain, renderTarget.renderTarget, out.address, cb);
|
||||
Viewer_captureRenderTargetRenderThread(_viewer!, view.view,
|
||||
swapChain.swapChain, renderTarget.renderTarget, out.address, cb);
|
||||
} else {
|
||||
Viewer_captureRenderThread(
|
||||
_viewer!, swapChain.swapChain, out.address, cb);
|
||||
_viewer!, view.view, swapChain.swapChain, out.address, cb);
|
||||
}
|
||||
});
|
||||
return out;
|
||||
@@ -569,54 +586,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
return entity;
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future panStart(double x, double y) async {
|
||||
grab_begin(_viewer!, x * pixelRatio, y * pixelRatio, true);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future panUpdate(double x, double y) async {
|
||||
grab_update(_viewer!, x * pixelRatio, y * pixelRatio);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future panEnd() async {
|
||||
grab_end(_viewer!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future rotateStart(double x, double y) async {
|
||||
grab_begin(_viewer!, x * pixelRatio, y * pixelRatio, false);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future rotateUpdate(double x, double y) async {
|
||||
grab_update(_viewer!, x * pixelRatio, y * pixelRatio);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future rotateEnd() async {
|
||||
grab_end(_viewer!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -1072,33 +1041,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
});
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future zoomBegin() async {
|
||||
scroll_begin(_viewer!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future zoomUpdate(double x, double y, double z) async {
|
||||
scroll_update(_viewer!, x, y, z);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future zoomEnd() async {
|
||||
scroll_end(_viewer!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -1167,7 +1109,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future setMainCamera() async {
|
||||
set_main_camera(_viewer!);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
Viewer_setMainCamera(_viewer!, view.view);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1198,11 +1141,14 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
Future setCamera(ThermionEntity entity, String? name) async {
|
||||
var cameraNamePtr =
|
||||
name?.toNativeUtf8(allocator: allocator).cast<Char>() ?? nullptr;
|
||||
var result = set_camera(_viewer!, entity, cameraNamePtr);
|
||||
allocator.free(cameraNamePtr);
|
||||
if (!result) {
|
||||
final camera =
|
||||
SceneManager_findCameraByName(_sceneManager!, entity, cameraNamePtr);
|
||||
if (camera == nullptr) {
|
||||
throw Exception("Failed to set camera");
|
||||
}
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
View_setCamera(view.view, camera);
|
||||
allocator.free(cameraNamePtr);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1218,7 +1164,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future setPostProcessing(bool enabled) async {
|
||||
set_post_processing_render_thread(_viewer!, enabled);
|
||||
final view = await getViewAt(0) as FFIView;
|
||||
View_setPostProcessing(view.view, enabled);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1226,14 +1173,16 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future setShadowsEnabled(bool enabled) async {
|
||||
set_shadows_enabled(_viewer!, enabled);
|
||||
final view = await getViewAt(0) as FFIView;
|
||||
View_setShadowsEnabled(view.view, enabled);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setShadowType(ShadowType shadowType) async {
|
||||
set_shadow_type(_viewer!, shadowType.index);
|
||||
final view = await getViewAt(0) as FFIView;
|
||||
View_setShadowType(view.view, shadowType.index);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1241,7 +1190,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
Future setSoftShadowOptions(
|
||||
double penumbraScale, double penumbraRatioScale) async {
|
||||
set_soft_shadow_options(_viewer!, penumbraScale, penumbraRatioScale);
|
||||
final view = await getViewAt(0) as FFIView;
|
||||
View_setSoftShadowOptions(view.view, penumbraScale, penumbraRatioScale);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1249,7 +1199,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa) async {
|
||||
set_antialiasing(_viewer!, msaa, fxaa, taa);
|
||||
final view = await getViewAt(0) as FFIView;
|
||||
View_setAntiAliasing(view.view, msaa, fxaa, taa);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1257,7 +1208,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future setBloom(double bloom) async {
|
||||
set_bloom_render_thread(_viewer!, bloom);
|
||||
final view = await getViewAt(0) as FFIView;
|
||||
View_setBloom(view.view, bloom);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1489,7 +1441,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
Future queuePositionUpdateFromViewportCoords(
|
||||
ThermionEntity entity, double x, double y) async {
|
||||
queue_position_update_from_viewport_coords(_sceneManager!, entity, x, y);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
queue_position_update_from_viewport_coords(
|
||||
_sceneManager!, view.view, entity, x, y);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1566,8 +1520,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
void pick(int x, int y) async {
|
||||
x = (x * pixelRatio).ceil();
|
||||
y = (viewportDimensions.$2 - (y * pixelRatio)).ceil();
|
||||
|
||||
filament_pick(_viewer!, x, y, _onPickResultCallable.nativeFunction);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
filament_pick(
|
||||
_viewer!, view.view, x, y, _onPickResultCallable.nativeFunction);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1577,7 +1532,10 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
void pickGizmo(int x, int y) async {
|
||||
x = (x * pixelRatio).ceil();
|
||||
y = (viewportDimensions.$2 - (y * pixelRatio)).ceil();
|
||||
pick_gizmo(_sceneManager!, x, y, _onGizmoPickResultCallable.nativeFunction);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
final gizmo = SceneManager_getGizmo(_sceneManager!);
|
||||
Gizmo_pick(
|
||||
gizmo, view.view, x, y, _onGizmoPickResultCallable.nativeFunction);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1658,27 +1616,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
return rotationMatrix;
|
||||
}
|
||||
|
||||
ManipulatorMode _cameraMode = ManipulatorMode.ORBIT;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future setCameraManipulatorOptions(
|
||||
{ManipulatorMode? mode,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01}) async {
|
||||
if (mode != null) {
|
||||
_cameraMode = mode;
|
||||
}
|
||||
if (_cameraMode != ManipulatorMode.ORBIT) {
|
||||
throw Exception("Manipulator mode $mode not yet implemented");
|
||||
}
|
||||
set_camera_manipulator_options(
|
||||
_viewer!, _cameraMode.index, orbitSpeedX, orbitSpeedX, zoomSpeed);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -1908,7 +1845,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future<v64.Aabb2> getViewportBoundingBox(ThermionEntity entityId) async {
|
||||
final result = get_bounding_box(_sceneManager!, entityId);
|
||||
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));
|
||||
}
|
||||
@@ -1916,17 +1854,16 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setLayerVisibility(int layer, bool visible) {
|
||||
set_layer_visibility(_sceneManager!, layer, visible);
|
||||
return Future.value();
|
||||
Future setLayerVisibility(int layer, bool visible) async {
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
View_setLayerEnabled(view.view, layer, visible);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setVisibilityLayer(ThermionEntity entity, int layer) {
|
||||
set_visibility_layer(_sceneManager!, entity, layer);
|
||||
return Future.value();
|
||||
Future setVisibilityLayer(ThermionEntity entity, int layer) async {
|
||||
SceneManager_setVisibilityLayer(_sceneManager!, entity, layer);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -2171,14 +2108,16 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
Future setActiveCamera(ThermionFFICamera camera) async {
|
||||
SceneManager_setCamera(_sceneManager!, camera.camera);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
View_setCamera(view.view, camera.camera);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Camera> getActiveCamera() async {
|
||||
final ptr = SceneManager_getActiveCamera(_sceneManager!);
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
final ptr = View_getCamera(view.view);
|
||||
return ThermionFFICamera(ptr, Viewer_getEngine(_viewer!));
|
||||
}
|
||||
|
||||
@@ -2216,6 +2155,15 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
}
|
||||
return ThermionFFICamera(camera, Viewer_getEngine(_viewer!));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<View> getViewAt(int index) async {
|
||||
var view = Viewer_getViewAt(_viewer!, index);
|
||||
if (view == nullptr) {
|
||||
throw Exception("Failed to get view");
|
||||
}
|
||||
return FFIView(view, _viewer!);
|
||||
}
|
||||
}
|
||||
|
||||
class ThermionFFITexture extends ThermionTexture {
|
||||
@@ -2270,3 +2218,20 @@ class FFISwapChain extends SwapChain {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class FFIView extends View {
|
||||
final Pointer<TView> view;
|
||||
final Pointer<TViewer> viewer;
|
||||
|
||||
FFIView(this.view, this.viewer);
|
||||
|
||||
@override
|
||||
Future updateViewport(int width, int height) async {
|
||||
View_updateViewport(view, width, height);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRenderTarget(covariant FFIRenderTarget renderTarget) async {
|
||||
View_setRenderTarget(view, renderTarget.renderTarget);
|
||||
}
|
||||
}
|
||||
|
||||
6
thermion_dart/lib/src/viewer/src/shared_types/view.dart
Normal file
6
thermion_dart/lib/src/viewer/src/shared_types/view.dart
Normal file
@@ -0,0 +1,6 @@
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
abstract class View {
|
||||
Future updateViewport(int width, int height);
|
||||
Future setRenderTarget(covariant RenderTarget renderTarget);
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import 'dart:async';
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
|
||||
import 'shared_types/swap_chain.dart';
|
||||
import 'shared_types/view.dart';
|
||||
|
||||
const double kNear = 0.05;
|
||||
const double kFar = 1000.0;
|
||||
@@ -72,7 +73,8 @@ abstract class ThermionViewer {
|
||||
///
|
||||
/// Render a single frame and copy the pixel buffer to [out].
|
||||
///
|
||||
Future<Uint8List> capture(covariant SwapChain swapChain, { covariant RenderTarget? renderTarget });
|
||||
Future<Uint8List> capture(covariant SwapChain swapChain,
|
||||
{covariant RenderTarget? renderTarget});
|
||||
|
||||
///
|
||||
///
|
||||
@@ -82,13 +84,23 @@ abstract class ThermionViewer {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<RenderTarget> createRenderTarget(int width, int height, int textureHandle);
|
||||
Future<RenderTarget> createRenderTarget(
|
||||
int width, int height, int textureHandle);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setRenderTarget(covariant RenderTarget renderTarget);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<View> createView();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<View> getViewAt(int index);
|
||||
|
||||
///
|
||||
/// Sets the framerate for continuous rendering when [setRendering] is enabled.
|
||||
@@ -246,36 +258,6 @@ abstract class ThermionViewer {
|
||||
Future<ThermionEntity> loadGltf(String path, String relativeResourcePath,
|
||||
{bool keepData = false});
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panStart(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panUpdate(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panEnd();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateStart(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateUpdate(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateEnd();
|
||||
|
||||
///
|
||||
/// Set the weights for all morph targets in [entity] to [weights].
|
||||
/// Note that [weights] must contain values for ALL morph targets, but no exception will be thrown if you don't do so (you'll just get incorrect results).
|
||||
@@ -418,20 +400,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future clearEntities();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomBegin();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomUpdate(double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomEnd();
|
||||
|
||||
///
|
||||
/// Schedules the glTF animation at [index] in [entity] to start playing on the next frame.
|
||||
@@ -746,17 +714,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
String? getNameForEntity(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the options for manipulating the camera via the viewport.
|
||||
/// ManipulatorMode.FREE_FLIGHT and ManipulatorMode.MAP are currently unsupported and will throw an exception.
|
||||
///
|
||||
@Deprecated("Use InputHandler instead")
|
||||
Future setCameraManipulatorOptions(
|
||||
{ManipulatorMode mode = ManipulatorMode.ORBIT,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01});
|
||||
|
||||
///
|
||||
/// Returns all child entities under [parent].
|
||||
///
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/swap_chain.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/view.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:async';
|
||||
@@ -385,12 +386,7 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future render() {
|
||||
// TODO: implement render
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
// TODO: implement rendering
|
||||
bool get rendering => throw UnimplementedError();
|
||||
@@ -1032,6 +1028,30 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
// TODO: implement setRenderTarget
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> capture(covariant SwapChain swapChain, {covariant RenderTarget? renderTarget}) {
|
||||
// TODO: implement capture
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<View> createView() {
|
||||
// TODO: implement createView
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<View> getViewAt(int index) {
|
||||
// TODO: implement getViewAt
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future render(covariant SwapChain swapChain) {
|
||||
// TODO: implement render
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1803,26 +1803,6 @@ class ThermionViewerWasm implements ThermionViewer {
|
||||
null);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setCameraManipulatorOptions(
|
||||
{ManipulatorMode mode = ManipulatorMode.ORBIT,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01}) async {
|
||||
_module!.ccall(
|
||||
"set_camera_manipulator_options",
|
||||
"void",
|
||||
["void*".toJS, "int".toJS, "double".toJS, "double".toJS, "double".toJS]
|
||||
.toJS,
|
||||
[
|
||||
_viewer!,
|
||||
mode.index.toJS,
|
||||
orbitSpeedX.toJS,
|
||||
orbitSpeedY.toJS,
|
||||
zoomSpeed.toJS
|
||||
].toJS,
|
||||
null);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setCameraModelMatrix(List<double> matrix) async {
|
||||
|
||||
@@ -17,6 +17,8 @@ extern "C"
|
||||
typedef struct TSceneManager TSceneManager;
|
||||
typedef struct TRenderTarget TRenderTarget;
|
||||
typedef struct TSwapChain TSwapChain;
|
||||
typedef struct TView TView;
|
||||
typedef struct TGizmo TGizmo;
|
||||
|
||||
struct TMaterialKey {
|
||||
bool doubleSided = 1;
|
||||
|
||||
@@ -61,8 +61,9 @@ namespace thermion_filament
|
||||
FilamentViewer(const void *context, const ResourceLoaderWrapperImpl *const resourceLoaderWrapper, void *const platform = nullptr, const char *uberArchivePath = nullptr);
|
||||
~FilamentViewer();
|
||||
|
||||
void setToneMapping(ToneMapping toneMapping);
|
||||
void setBloom(float strength);
|
||||
View* createView();
|
||||
View* getViewAt(int index);
|
||||
|
||||
void loadSkybox(const char *const skyboxUri);
|
||||
void removeSkybox();
|
||||
|
||||
@@ -74,17 +75,16 @@ namespace thermion_filament
|
||||
void removeEntity(EntityId asset);
|
||||
void clearEntities();
|
||||
|
||||
void updateViewport(uint32_t width, uint32_t height);
|
||||
bool render(
|
||||
uint64_t frameTimeInNanos,
|
||||
View* view,
|
||||
SwapChain* swapChain,
|
||||
void *pixelBuffer,
|
||||
void (*callback)(void *buf, size_t size, void *data),
|
||||
void *data);
|
||||
void setFrameInterval(float interval);
|
||||
|
||||
bool setCamera(EntityId asset, const char *nodeName);
|
||||
void setMainCamera();
|
||||
void setMainCamera(View *view);
|
||||
EntityId getMainCamera();
|
||||
Camera* getCamera(EntityId entity);
|
||||
|
||||
@@ -96,25 +96,15 @@ namespace thermion_filament
|
||||
|
||||
RenderTarget* createRenderTarget(intptr_t textureId, uint32_t width, uint32_t height);
|
||||
void destroyRenderTarget(RenderTarget* renderTarget);
|
||||
void setRenderTarget(RenderTarget* renderTarget);
|
||||
|
||||
Renderer *getRenderer();
|
||||
|
||||
void setBackgroundColor(const float r, const float g, const float b, const float a);
|
||||
void setBackgroundImage(const char *resourcePath, bool fillHeight);
|
||||
void setBackgroundImage(const char *resourcePath, bool fillHeight, uint32_t width, uint32_t height);
|
||||
void clearBackgroundImage();
|
||||
void setBackgroundImagePosition(float x, float y, bool clamp);
|
||||
|
||||
void setViewFrustumCulling(bool enabled);
|
||||
|
||||
void setCameraManipulatorOptions(filament::camutils::Mode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed);
|
||||
void grabBegin(float x, float y, bool pan);
|
||||
void grabUpdate(float x, float y);
|
||||
void grabEnd();
|
||||
void scrollBegin();
|
||||
void scrollUpdate(float x, float y, float delta);
|
||||
void scrollEnd();
|
||||
void pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||
void setBackgroundImagePosition(float x, float y, bool clamp, uint32_t width, uint32_t height);
|
||||
|
||||
void pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||
Engine* getEngine() {
|
||||
return _engine;
|
||||
}
|
||||
@@ -140,16 +130,9 @@ namespace thermion_filament
|
||||
void setLightDirection(EntityId entityId, float x, float y, float z);
|
||||
void removeLight(EntityId entityId);
|
||||
void clearLights();
|
||||
void setPostProcessing(bool enabled);
|
||||
|
||||
void capture(uint8_t *out, bool useFence, SwapChain* swapChain, void (*onComplete)());
|
||||
void capture(uint8_t *out, bool useFence, SwapChain* swapChain, RenderTarget* renderTarget, void (*onComplete)());
|
||||
|
||||
void setAntiAliasing(bool msaaEnabled, bool fxaaEnabled, bool taaEnabled);
|
||||
void setDepthOfField();
|
||||
void setShadowsEnabled(bool enabled);
|
||||
void setShadowType(ShadowType shadowType);
|
||||
void setSoftShadowOptions( float penumbraScale, float penumbraRatioScale);
|
||||
void capture(View* view, uint8_t *out, bool useFence, SwapChain* swapChain, void (*onComplete)());
|
||||
void capture(View* view, uint8_t *out, bool useFence, SwapChain* swapChain, RenderTarget* renderTarget, void (*onComplete)());
|
||||
|
||||
SceneManager *const getSceneManager()
|
||||
{
|
||||
@@ -162,13 +145,13 @@ namespace thermion_filament
|
||||
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
||||
void* _context = nullptr;
|
||||
Scene *_scene = nullptr;
|
||||
View *_view = nullptr;
|
||||
Engine *_engine = nullptr;
|
||||
thermion_filament::ThreadPool *_tp = nullptr;
|
||||
Renderer *_renderer = nullptr;
|
||||
SceneManager *_sceneManager = nullptr;
|
||||
std::vector<RenderTarget*> _renderTargets;
|
||||
std::vector<SwapChain*> _swapChains;
|
||||
std::vector<View*> _views;
|
||||
|
||||
std::mutex _renderMutex; // mutex to ensure thread safety when removing assets
|
||||
|
||||
@@ -183,16 +166,6 @@ namespace thermion_filament
|
||||
// Camera properties
|
||||
Camera *_mainCamera = nullptr; // the default camera added to every scene. If you want the *active* camera, access via View.
|
||||
|
||||
Manipulator<double> *_manipulator = nullptr;
|
||||
filament::camutils::Mode _manipulatorMode = filament::camutils::Mode::ORBIT;
|
||||
double _orbitSpeedX = 0.01;
|
||||
double _orbitSpeedY = 0.01;
|
||||
double _zoomSpeed = 0.01;
|
||||
|
||||
void _createManipulator();
|
||||
|
||||
ColorGrading *colorGrading = nullptr;
|
||||
|
||||
// background image properties
|
||||
uint32_t _imageHeight = 0;
|
||||
uint32_t _imageWidth = 0;
|
||||
|
||||
@@ -58,7 +58,7 @@ class Gizmo {
|
||||
};
|
||||
|
||||
public:
|
||||
Gizmo(Engine& engine, View *view, Scene *scene);
|
||||
Gizmo(Engine& engine, Scene *scene);
|
||||
~Gizmo();
|
||||
|
||||
Entity x() {
|
||||
@@ -73,15 +73,12 @@ class Gizmo {
|
||||
Entity center() {
|
||||
return _entities[3];
|
||||
};
|
||||
View* view() {
|
||||
return _view;
|
||||
}
|
||||
|
||||
bool isActive() {
|
||||
return _isActive;
|
||||
}
|
||||
|
||||
void pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||
void pick(View* view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||
bool isGizmoEntity(Entity entity);
|
||||
void setVisibility(bool visible);
|
||||
|
||||
@@ -90,9 +87,7 @@ class Gizmo {
|
||||
void highlight(Entity entity);
|
||||
void unhighlight();
|
||||
Engine &_engine;
|
||||
View *_view;
|
||||
Scene *_scene;
|
||||
filament::Camera *_camera;
|
||||
utils::Entity _entities[7] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
|
||||
Material* _material;
|
||||
MaterialInstance* _materialInstances[7];
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace thermion_filament
|
||||
class SceneManager
|
||||
{
|
||||
public:
|
||||
SceneManager(View* view,
|
||||
SceneManager(
|
||||
const ResourceLoaderWrapperImpl *const loader,
|
||||
Engine *engine,
|
||||
Scene *scene,
|
||||
@@ -111,9 +111,9 @@ namespace thermion_filament
|
||||
void setRotation(EntityId e, float rads, float x, float y, float z, float w);
|
||||
|
||||
void queueTransformUpdates(EntityId* entities, math::mat4* transforms, int numEntities);
|
||||
|
||||
void queueRelativePositionUpdateWorldAxis(EntityId entity, float viewportCoordX, float viewportCoordY, float x, float y, float z);
|
||||
void queueRelativePositionUpdateFromViewportVector(EntityId entityId, float viewportCoordX, float viewportCoordY);
|
||||
void queueRelativePositionUpdateFromViewportVector(View* view, EntityId entityId, float viewportCoordX, float viewportCoordY);
|
||||
|
||||
const utils::Entity *getCameraEntities(EntityId e);
|
||||
size_t getCameraEntityCount(EntityId e);
|
||||
const utils::Entity *getLightEntities(EntityId e) noexcept;
|
||||
@@ -231,12 +231,7 @@ namespace thermion_filament
|
||||
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
|
||||
/// @return
|
||||
///
|
||||
Aabb2 getBoundingBox(EntityId entity);
|
||||
|
||||
///
|
||||
/// Toggles the visibility of the given layer.
|
||||
///
|
||||
void setLayerVisibility(SceneManager::LAYERS layer, bool enabled);
|
||||
Aabb2 getBoundingBox(View* view, EntityId entity);
|
||||
|
||||
///
|
||||
/// Creates an entity with the specified geometry/material/normals and adds to the scene.
|
||||
@@ -308,20 +303,15 @@ namespace thermion_filament
|
||||
|
||||
void destroyCamera(Camera* camera);
|
||||
|
||||
void setCamera(Camera* camera);
|
||||
|
||||
size_t getCameraCount();
|
||||
|
||||
Camera* getCameraAt(size_t index);
|
||||
|
||||
Camera* getActiveCamera();
|
||||
|
||||
private:
|
||||
gltfio::AssetLoader *_assetLoader = nullptr;
|
||||
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
||||
Engine *_engine = nullptr;
|
||||
Scene *_scene = nullptr;
|
||||
View* _view = nullptr;
|
||||
Camera* _mainCamera;
|
||||
|
||||
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
|
||||
|
||||
15
thermion_dart/native/include/TGizmo.h
Normal file
15
thermion_dart/native/include/TGizmo.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, TView *tView, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
79
thermion_dart/native/include/TView.h
Normal file
79
thermion_dart/native/include/TView.h
Normal file
@@ -0,0 +1,79 @@
|
||||
#ifndef _FLUTTER_FILAMENT_API_H
|
||||
#define _FLUTTER_FILAMENT_API_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef IS_DLL
|
||||
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
|
||||
#else
|
||||
#define EMSCRIPTEN_KEEPALIVE __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
#ifndef EMSCRIPTEN_KEEPALIVE
|
||||
#define EMSCRIPTEN_KEEPALIVE __attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// we copy the LLVM <stdbool.h> here rather than including,
|
||||
// because on Windows it's difficult to pin the exact location which confuses dart ffigen
|
||||
|
||||
#ifndef __STDBOOL_H
|
||||
#define __STDBOOL_H
|
||||
|
||||
#define __bool_true_false_are_defined 1
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L
|
||||
/* FIXME: We should be issuing a deprecation warning here, but cannot yet due
|
||||
* to system headers which include this header file unconditionally.
|
||||
*/
|
||||
#elif !defined(__cplusplus)
|
||||
#define bool _Bool
|
||||
#define true 1
|
||||
#define false 0
|
||||
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/* Define _Bool as a GNU extension. */
|
||||
#define _Bool bool
|
||||
#if defined(__cplusplus) && __cplusplus < 201103L
|
||||
/* For C++98, define bool, false, true as a GNU extension. */
|
||||
#define bool bool
|
||||
#define false false
|
||||
#define true true
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __STDBOOL_H */
|
||||
|
||||
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "APIBoundaryTypes.h"
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// View
|
||||
EMSCRIPTEN_KEEPALIVE void View_updateViewport(TView *view, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setRenderTarget(TView *view, TRenderTarget *renderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setFrustumCullingEnabled(TView *view, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_updateViewport(TView* tView, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setRenderTarget(TView* tView, TRenderTarget* tRenderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setFrustumCullingEnabled(TView* tView, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setPostProcessing(TView* tView, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setShadowsEnabled(TView* tView, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setShadowType(TView* tView, int shadowType);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setSoftShadowOptions(TView* tView, float penumbraScale, float penumbraRatioScale);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setBloom(TView* tView, float strength);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setToneMapping(TView* tView, TEngine* tEngine, int toneMapping);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setAntiAliasing(TView *tView, bool msaa, bool fxaa, bool taa);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setLayerEnabled(TView *tView, int layer, bool visible);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setCamera(TView *tView, TCamera *tCamera);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* View_getCamera(TView *tView);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -59,11 +59,11 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *viewer, TSwapChain* swapChain);
|
||||
EMSCRIPTEN_KEEPALIVE bool Viewer_render(
|
||||
TViewer *viewer,
|
||||
TView *view,
|
||||
TSwapChain *swapChain,
|
||||
uint64_t frameTimeInNanos,
|
||||
void *pixelBuffer,
|
||||
@@ -71,16 +71,20 @@ extern "C"
|
||||
void *data);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
|
||||
TViewer *viewer,
|
||||
TView *view,
|
||||
TSwapChain *swapChain,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void));
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget(
|
||||
TViewer *viewer,
|
||||
TView *view,
|
||||
TSwapChain *swapChain,
|
||||
TRenderTarget *renderTarget,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TView* Viewer_createView(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE TView* Viewer_getViewAt(TViewer *viewer, int index);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView);
|
||||
|
||||
// Engine
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer);
|
||||
@@ -92,7 +96,7 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image(TViewer *viewer, const char *path, bool fillHeight);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image_position(TViewer *viewer, float x, float y, bool clamp);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_color(TViewer *viewer, const float r, const float g, const float b, const float a);
|
||||
EMSCRIPTEN_KEEPALIVE void set_tone_mapping(TViewer *viewer, int toneMapping);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_bloom(TViewer *viewer, float strength);
|
||||
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath);
|
||||
EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity);
|
||||
@@ -128,20 +132,12 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE EntityId create_instance(TSceneManager *sceneManager, EntityId id);
|
||||
EMSCRIPTEN_KEEPALIVE int get_instance_count(TSceneManager *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void get_instances(TSceneManager *sceneManager, EntityId entityId, EntityId *out);
|
||||
EMSCRIPTEN_KEEPALIVE void set_main_camera(TViewer *viewer);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_camera(TViewer *viewer, EntityId entity, const char *nodeName);
|
||||
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_frame_interval(TViewer *viewer, float interval);
|
||||
EMSCRIPTEN_KEEPALIVE void update_viewport(TViewer *viewer, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_begin(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_update(TViewer *viewer, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_end(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void grab_begin(TViewer *viewer, float x, float y, bool pan);
|
||||
EMSCRIPTEN_KEEPALIVE void grab_update(TViewer *viewer, float x, float y);
|
||||
EMSCRIPTEN_KEEPALIVE void grab_end(TViewer *viewer);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void apply_weights(
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
@@ -213,6 +209,9 @@ extern "C"
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setTransform(TSceneManager *sceneManager, EntityId entityId, const double *const transform);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *sceneManager, EntityId* entities, const double* const transforms, int numEntities);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE TGizmo* SceneManager_getGizmo(TSceneManager *tSceneManager);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index);
|
||||
@@ -223,7 +222,7 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void transform_to_unit_cube(TSceneManager *sceneManager, EntityId asset);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void queue_relative_position_update_world_axis(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, TView *view, EntityId entity, float viewportX, float viewportY);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_position(TSceneManager *sceneManager, EntityId entity, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void set_rotation(TSceneManager *sceneManager, EntityId entity, float rads, float x, float y, float z, float w);
|
||||
@@ -252,7 +251,6 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_culling_far(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float focusDistance);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_manipulator_options(TViewer *viewer, _ManipulatorMode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix);
|
||||
@@ -264,22 +262,15 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
|
||||
|
||||
// SceneManager
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_createCamera(TSceneManager *sceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *sceneManager, TCamera* camera);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_setCamera(TSceneManager *sceneManager, TCamera* camera);
|
||||
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *sceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *sceneManager, size_t index);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getActiveCamera(TSceneManager *sceneManager);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE int hide_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
|
||||
EMSCRIPTEN_KEEPALIVE int reveal_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
|
||||
EMSCRIPTEN_KEEPALIVE void set_post_processing(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void set_shadows_enabled(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void set_shadow_type(TViewer *viewer, int shadowType);
|
||||
EMSCRIPTEN_KEEPALIVE void set_soft_shadow_options(TViewer *viewer, float penumbraScale, float penumbraRatioScale);
|
||||
EMSCRIPTEN_KEEPALIVE void set_antialiasing(TViewer *viewer, bool msaa, bool fxaa, bool taa);
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *viewer, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *viewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(TSceneManager *sceneManager, const EntityId parent, const char *name);
|
||||
EMSCRIPTEN_KEEPALIVE int get_entity_count(TSceneManager *sceneManager, const EntityId target, bool renderableOnly);
|
||||
@@ -312,11 +303,9 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void test_collisions(TSceneManager *sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_priority(TSceneManager *sceneManager, EntityId entityId, int priority);
|
||||
EMSCRIPTEN_KEEPALIVE void get_gizmo(TSceneManager *sceneManager, EntityId *out);
|
||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
|
||||
EMSCRIPTEN_KEEPALIVE void set_layer_visibility(TSceneManager *sceneManager, int layer, bool visible);
|
||||
EMSCRIPTEN_KEEPALIVE void set_visibility_layer(TSceneManager *sceneManager, EntityId entity, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE void pick_gizmo(TSceneManager *sceneManager, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *view, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *view, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_gizmo_visibility(TSceneManager *sceneManager, bool visible);
|
||||
EMSCRIPTEN_KEEPALIVE void set_stencil_highlight(TSceneManager *sceneManager, EntityId entity, float r, float g, float b);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_stencil_highlight(TSceneManager *sceneManager, EntityId entity);
|
||||
|
||||
@@ -27,9 +27,9 @@ extern "C"
|
||||
void (*callback)(TViewer *viewer));
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer, void *const surface, uint32_t width, uint32_t height, void (*onComplete)(TSwapChain*));
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChainRenderThread(TViewer *viewer, TSwapChain* swapChain, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TSwapChain* swapChain);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TSwapChain* swapChain, uint8_t* out, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, uint8_t* out, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer_render_thread(TViewer *viewer);
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void remove_entity_render_thread(TViewer *viewer, EntityId asset, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void clear_entities_render_thread(TViewer *viewer, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_render_thread(TViewer *viewer, EntityId asset, const char *nodeName, void (*callback)(bool));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void apply_weights_render_thread(
|
||||
TSceneManager *sceneManager,
|
||||
EntityId asset,
|
||||
|
||||
@@ -164,31 +164,7 @@ namespace thermion_filament
|
||||
|
||||
_mainCamera = _engine->createCamera(camera);
|
||||
|
||||
_view = _engine->createView();
|
||||
_view->setBlendMode(filament::View::BlendMode::TRANSLUCENT);
|
||||
_view->setStencilBufferEnabled(true);
|
||||
|
||||
setToneMapping(ToneMapping::ACES);
|
||||
|
||||
// there's a glitch on certain iGPUs where nothing will render when postprocessing is enabled and bloom is disabled
|
||||
// set bloom to a small value here
|
||||
setBloom(0.01);
|
||||
|
||||
_view->setAmbientOcclusionOptions({.enabled = false});
|
||||
_view->setDynamicResolutionOptions({.enabled = false});
|
||||
|
||||
#if defined(_WIN32)
|
||||
_view->setStereoscopicOptions({.enabled = true});
|
||||
#endif
|
||||
|
||||
_view->setDithering(filament::Dithering::NONE);
|
||||
setAntiAliasing(false, false, false);
|
||||
_view->setShadowingEnabled(false);
|
||||
_view->setScreenSpaceRefractionEnabled(false);
|
||||
setPostProcessing(false);
|
||||
|
||||
_view->setScene(_scene);
|
||||
_view->setCamera(_mainCamera);
|
||||
createView();
|
||||
|
||||
const float aperture = _mainCamera->getAperture();
|
||||
const float shutterSpeed = _mainCamera->getShutterSpeed();
|
||||
@@ -197,7 +173,6 @@ namespace thermion_filament
|
||||
EntityManager &em = EntityManager::get();
|
||||
|
||||
_sceneManager = new SceneManager(
|
||||
_view,
|
||||
_resourceLoaderWrapper,
|
||||
_engine,
|
||||
_scene,
|
||||
@@ -205,80 +180,6 @@ namespace thermion_filament
|
||||
_mainCamera);
|
||||
}
|
||||
|
||||
void FilamentViewer::setAntiAliasing(bool msaa, bool fxaa, bool taa)
|
||||
{
|
||||
View::MultiSampleAntiAliasingOptions multiSampleAntiAliasingOptions;
|
||||
multiSampleAntiAliasingOptions.enabled = msaa;
|
||||
|
||||
_view->setMultiSampleAntiAliasingOptions(multiSampleAntiAliasingOptions);
|
||||
TemporalAntiAliasingOptions taaOpts;
|
||||
taaOpts.enabled = taa;
|
||||
_view->setTemporalAntiAliasingOptions(taaOpts);
|
||||
_view->setAntiAliasing(fxaa ? AntiAliasing::FXAA : AntiAliasing::NONE);
|
||||
}
|
||||
|
||||
void FilamentViewer::setPostProcessing(bool enabled)
|
||||
{
|
||||
_view->setPostProcessingEnabled(enabled);
|
||||
}
|
||||
|
||||
void FilamentViewer::setShadowsEnabled(bool enabled)
|
||||
{
|
||||
_view->setShadowingEnabled(enabled);
|
||||
}
|
||||
|
||||
void FilamentViewer::setShadowType(ShadowType shadowType)
|
||||
{
|
||||
_view->setShadowType(shadowType);
|
||||
}
|
||||
|
||||
void FilamentViewer::setSoftShadowOptions(float penumbraScale, float penumbraRatioScale)
|
||||
{
|
||||
SoftShadowOptions opts;
|
||||
opts.penumbraRatioScale = penumbraRatioScale;
|
||||
opts.penumbraScale = penumbraScale;
|
||||
_view->setSoftShadowOptions(opts);
|
||||
}
|
||||
|
||||
void FilamentViewer::setBloom(float strength)
|
||||
{
|
||||
#ifndef __EMSCRIPTEN__
|
||||
decltype(_view->getBloomOptions()) opts;
|
||||
opts.enabled = true;
|
||||
opts.strength = strength;
|
||||
_view->setBloomOptions(opts);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FilamentViewer::setToneMapping(ToneMapping toneMapping)
|
||||
{
|
||||
|
||||
ToneMapper *tm;
|
||||
switch (toneMapping)
|
||||
{
|
||||
case ToneMapping::ACES:
|
||||
Log("Setting tone mapping to ACES");
|
||||
tm = new ACESToneMapper();
|
||||
break;
|
||||
case ToneMapping::LINEAR:
|
||||
Log("Setting tone mapping to Linear");
|
||||
tm = new LinearToneMapper();
|
||||
break;
|
||||
case ToneMapping::FILMIC:
|
||||
Log("Setting tone mapping to Filmic");
|
||||
tm = new FilmicToneMapper();
|
||||
break;
|
||||
default:
|
||||
Log("ERROR: Unsupported tone mapping");
|
||||
return;
|
||||
}
|
||||
|
||||
auto newColorGrading = ColorGrading::Builder().toneMapper(tm).build(*_engine);
|
||||
_view->setColorGrading(newColorGrading);
|
||||
_engine->destroy(colorGrading);
|
||||
delete tm;
|
||||
}
|
||||
|
||||
void FilamentViewer::setFrameInterval(float frameInterval)
|
||||
{
|
||||
_frameInterval = frameInterval;
|
||||
@@ -307,7 +208,7 @@ namespace thermion_filament
|
||||
bool shadows)
|
||||
{
|
||||
auto light = EntityManager::get().create();
|
||||
|
||||
|
||||
auto result = LightManager::Builder(t)
|
||||
.color(Color::cct(colour))
|
||||
.intensity(intensity)
|
||||
@@ -333,36 +234,38 @@ namespace thermion_filament
|
||||
return Entity::smuggle(light);
|
||||
}
|
||||
|
||||
void FilamentViewer::setLightPosition(EntityId entityId, float x, float y, float z) {
|
||||
void FilamentViewer::setLightPosition(EntityId entityId, float x, float y, float z)
|
||||
{
|
||||
auto light = Entity::import(entityId);
|
||||
|
||||
if(light.isNull()) {
|
||||
if (light.isNull())
|
||||
{
|
||||
Log("Light not found for entity %d", entityId);
|
||||
return;
|
||||
}
|
||||
|
||||
auto& lm = _engine->getLightManager();
|
||||
auto &lm = _engine->getLightManager();
|
||||
|
||||
auto instance = lm.getInstance(light);
|
||||
|
||||
lm.setPosition(instance, filament::math::float3 { x, y, z });
|
||||
|
||||
lm.setPosition(instance, filament::math::float3{x, y, z});
|
||||
}
|
||||
|
||||
void FilamentViewer::setLightDirection(EntityId entityId, float x, float y, float z) {
|
||||
void FilamentViewer::setLightDirection(EntityId entityId, float x, float y, float z)
|
||||
{
|
||||
auto light = Entity::import(entityId);
|
||||
|
||||
if(light.isNull()) {
|
||||
if (light.isNull())
|
||||
{
|
||||
Log("Light not found for entity %d", entityId);
|
||||
return;
|
||||
}
|
||||
|
||||
auto& lm = _engine->getLightManager();
|
||||
auto &lm = _engine->getLightManager();
|
||||
|
||||
auto instance = lm.getInstance(light);
|
||||
|
||||
lm.setDirection(instance, filament::math::float3 { x, y, z });
|
||||
|
||||
lm.setDirection(instance, filament::math::float3{x, y, z});
|
||||
}
|
||||
|
||||
void FilamentViewer::removeLight(EntityId entityId)
|
||||
@@ -608,7 +511,7 @@ namespace thermion_filament
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentViewer::setBackgroundImage(const char *resourcePath, bool fillHeight)
|
||||
void FilamentViewer::setBackgroundImage(const char *resourcePath, bool fillHeight, uint32_t width, uint32_t height)
|
||||
{
|
||||
|
||||
std::lock_guard lock(_imageMutex);
|
||||
@@ -624,9 +527,7 @@ namespace thermion_filament
|
||||
|
||||
// This currently just anchors the image at the bottom left of the viewport at its original size
|
||||
// TODO - implement stretch/etc
|
||||
const Viewport &vp = _view->getViewport();
|
||||
|
||||
float xScale = float(vp.width) / float(_imageWidth);
|
||||
float xScale = float(width) / float(_imageWidth);
|
||||
|
||||
float yScale;
|
||||
if (fillHeight)
|
||||
@@ -635,7 +536,7 @@ namespace thermion_filament
|
||||
}
|
||||
else
|
||||
{
|
||||
yScale = float(vp.height) / float(_imageHeight);
|
||||
yScale = float(height) / float(_imageHeight);
|
||||
}
|
||||
|
||||
_imageScale = mat4f{xScale, 0.0f, 0.0f, 0.0f, 0.0f, yScale, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
@@ -643,7 +544,6 @@ namespace thermion_filament
|
||||
_imageMaterial->setDefaultParameter("transform", _imageScale);
|
||||
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
|
||||
_imageMaterial->setDefaultParameter("showImage", 1);
|
||||
|
||||
}
|
||||
|
||||
///
|
||||
@@ -652,7 +552,7 @@ namespace thermion_filament
|
||||
/// are positioned at a max/min of -1/1 respectively
|
||||
/// (i.e. you cannot set a position where the left/top or right/bottom sides would be "inside" the screen coordinate space).
|
||||
///
|
||||
void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp = false)
|
||||
void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp = false, uint32_t width = 0, uint32_t height = 0)
|
||||
{
|
||||
std::lock_guard lock(_imageMutex);
|
||||
|
||||
@@ -678,8 +578,8 @@ namespace thermion_filament
|
||||
{
|
||||
Log("Clamping background image translation");
|
||||
// first, clamp x/y
|
||||
auto xScale = float(_imageWidth) / _view->getViewport().width;
|
||||
auto yScale = float(_imageHeight) / _view->getViewport().height;
|
||||
auto xScale = float(_imageWidth) / width;
|
||||
auto yScale = float(_imageHeight) / height;
|
||||
|
||||
float xMin = 0;
|
||||
float xMax = 0;
|
||||
@@ -720,31 +620,30 @@ namespace thermion_filament
|
||||
// i.e. translating the image right by 0.5 units means translating the UV coordinates left by 0.5 units.
|
||||
x = -x;
|
||||
y = -y;
|
||||
Log("x %f y %f", x, y);
|
||||
|
||||
Log("imageScale %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ", _imageScale[0][0], _imageScale[0][1], _imageScale[0][2], _imageScale[0][3],
|
||||
_imageScale[1][0], _imageScale[1][1], _imageScale[1][2], _imageScale[1][3],
|
||||
_imageScale[2][0], _imageScale[2][1], _imageScale[2][2], _imageScale[2][3],
|
||||
_imageScale[3][0], _imageScale[3][1], _imageScale[3][2], _imageScale[3][3]);
|
||||
|
||||
auto transform = math::mat4f::translation(filament::math::float3(x, y, 0.0f)) * _imageScale;
|
||||
|
||||
Log("transform %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ", transform[0][0], transform[0][1], transform[0][2], transform[0][3],
|
||||
transform[1][0], transform[1][1], transform[1][2], transform[1][3],
|
||||
transform[2][0], transform[2][1], transform[2][2], transform[2][3],
|
||||
transform[3][0], transform[3][1], transform[3][2], transform[3][3]);
|
||||
_imageMaterial->setDefaultParameter("transform", transform);
|
||||
}
|
||||
|
||||
FilamentViewer::~FilamentViewer()
|
||||
{
|
||||
clearLights();
|
||||
for(auto swapChain : _swapChains) {
|
||||
|
||||
for (auto view : _views)
|
||||
{
|
||||
_engine->destroy(view);
|
||||
}
|
||||
|
||||
_views.clear();
|
||||
|
||||
for (auto swapChain : _swapChains)
|
||||
{
|
||||
_engine->destroy(swapChain);
|
||||
}
|
||||
|
||||
_swapChains.clear();
|
||||
|
||||
|
||||
if (!_imageEntity.isNull())
|
||||
{
|
||||
_engine->destroy(_imageEntity);
|
||||
@@ -756,7 +655,6 @@ namespace thermion_filament
|
||||
delete _sceneManager;
|
||||
_engine->destroyCameraComponent(_mainCamera->getEntity());
|
||||
_mainCamera = nullptr;
|
||||
_engine->destroy(_view);
|
||||
_engine->destroy(_scene);
|
||||
_engine->destroy(_renderer);
|
||||
Engine::destroy(&_engine);
|
||||
@@ -765,10 +663,10 @@ namespace thermion_filament
|
||||
|
||||
Renderer *FilamentViewer::getRenderer() { return _renderer; }
|
||||
|
||||
SwapChain* FilamentViewer::createSwapChain(const void *window, uint32_t width, uint32_t height)
|
||||
SwapChain *FilamentViewer::createSwapChain(const void *window, uint32_t width, uint32_t height)
|
||||
{
|
||||
std::lock_guard lock(_renderMutex);
|
||||
SwapChain* swapChain;
|
||||
SwapChain *swapChain;
|
||||
#if TARGET_OS_IPHONE
|
||||
swapChain = _engine->createSwapChain((void *)window, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
|
||||
#else
|
||||
@@ -787,58 +685,58 @@ namespace thermion_filament
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
RenderTarget* FilamentViewer::createRenderTarget(intptr_t texture, uint32_t width, uint32_t height)
|
||||
RenderTarget *FilamentViewer::createRenderTarget(intptr_t texture, uint32_t width, uint32_t height)
|
||||
{
|
||||
// Create filament textures and render targets (note the color buffer has the import call)
|
||||
auto rtColor = filament::Texture::Builder()
|
||||
.width(width)
|
||||
.height(height)
|
||||
.levels(1)
|
||||
.usage(filament::Texture::Usage::COLOR_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
|
||||
.format(filament::Texture::InternalFormat::RGBA8)
|
||||
.import(texture)
|
||||
.build(*_engine);
|
||||
.width(width)
|
||||
.height(height)
|
||||
.levels(1)
|
||||
.usage(filament::Texture::Usage::COLOR_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
|
||||
.format(filament::Texture::InternalFormat::RGBA8)
|
||||
.import(texture)
|
||||
.build(*_engine);
|
||||
auto rtDepth = filament::Texture::Builder()
|
||||
.width(width)
|
||||
.height(height)
|
||||
.levels(1)
|
||||
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
|
||||
.format(filament::Texture::InternalFormat::DEPTH32F)
|
||||
.build(*_engine);
|
||||
.width(width)
|
||||
.height(height)
|
||||
.levels(1)
|
||||
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
|
||||
.format(filament::Texture::InternalFormat::DEPTH32F)
|
||||
.build(*_engine);
|
||||
auto rt = filament::RenderTarget::Builder()
|
||||
.texture(RenderTarget::AttachmentPoint::COLOR, rtColor)
|
||||
.texture(RenderTarget::AttachmentPoint::DEPTH, rtDepth)
|
||||
.build(*_engine);
|
||||
return rt;
|
||||
.texture(RenderTarget::AttachmentPoint::COLOR, rtColor)
|
||||
.texture(RenderTarget::AttachmentPoint::DEPTH, rtDepth)
|
||||
.build(*_engine);
|
||||
return rt;
|
||||
}
|
||||
|
||||
void FilamentViewer::destroyRenderTarget(RenderTarget* renderTarget) {
|
||||
void FilamentViewer::destroyRenderTarget(RenderTarget *renderTarget)
|
||||
{
|
||||
std::lock_guard lock(_renderMutex);
|
||||
auto rtDepth = renderTarget->getTexture(RenderTarget::AttachmentPoint::DEPTH);
|
||||
if(rtDepth) {
|
||||
if (rtDepth)
|
||||
{
|
||||
_engine->destroy(rtDepth);
|
||||
}
|
||||
auto rtColor = renderTarget->getTexture(RenderTarget::AttachmentPoint::COLOR);
|
||||
if(rtColor) {
|
||||
if (rtColor)
|
||||
{
|
||||
_engine->destroy(rtColor);
|
||||
}
|
||||
_engine->destroy(renderTarget);
|
||||
_engine->destroy(renderTarget);
|
||||
auto it = std::find(_renderTargets.begin(), _renderTargets.end(), renderTarget);
|
||||
if(it != _renderTargets.end()) {
|
||||
if (it != _renderTargets.end())
|
||||
{
|
||||
_renderTargets.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentViewer::setRenderTarget(RenderTarget *renderTarget) {
|
||||
std::lock_guard lock(_renderMutex);
|
||||
_view->setRenderTarget(renderTarget);
|
||||
}
|
||||
|
||||
void FilamentViewer::destroySwapChain(SwapChain *swapChain)
|
||||
{
|
||||
std::lock_guard lock(_renderMutex);
|
||||
auto it = std::find(_swapChains.begin(), _swapChains.end(), swapChain);
|
||||
if(it != _swapChains.end()) {
|
||||
if (it != _swapChains.end())
|
||||
{
|
||||
_swapChains.erase(it);
|
||||
}
|
||||
_engine->destroy(swapChain);
|
||||
@@ -850,9 +748,55 @@ namespace thermion_filament
|
||||
#endif
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
View *FilamentViewer::createView()
|
||||
{
|
||||
auto *view = _engine->createView();
|
||||
view->setLayerEnabled(SceneManager::LAYERS::DEFAULT_ASSETS, true);
|
||||
view->setLayerEnabled(SceneManager::LAYERS::BACKGROUND, true); // skybox + image
|
||||
view->setLayerEnabled(SceneManager::LAYERS::OVERLAY, false); // world grid + gizmo
|
||||
view->setBlendMode(filament::View::BlendMode::TRANSLUCENT);
|
||||
view->setStencilBufferEnabled(true);
|
||||
view->setAmbientOcclusionOptions({.enabled = false});
|
||||
view->setDynamicResolutionOptions({.enabled = false});
|
||||
#if defined(_WIN32)
|
||||
view->setStereoscopicOptions({.enabled = true});
|
||||
#endif
|
||||
|
||||
// there's a glitch on certain iGPUs where nothing will render when postprocessing is enabled and bloom is disabled
|
||||
// set bloom to a small value here
|
||||
view->setBloomOptions({.strength = 0.01});
|
||||
view->setDithering(filament::Dithering::NONE);
|
||||
view->setShadowingEnabled(false);
|
||||
view->setScreenSpaceRefractionEnabled(false);
|
||||
view->setPostProcessingEnabled(false);
|
||||
view->setScene(_scene);
|
||||
view->setCamera(_mainCamera);
|
||||
|
||||
_views.push_back(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
View *FilamentViewer::getViewAt(int32_t index)
|
||||
{
|
||||
Log("Getting view at %d", index);
|
||||
if (index < _views.size())
|
||||
{
|
||||
return _views[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @brief
|
||||
///
|
||||
///
|
||||
void FilamentViewer::clearEntities()
|
||||
{
|
||||
_view->setCamera(_mainCamera);
|
||||
_sceneManager->destroyAll();
|
||||
}
|
||||
|
||||
@@ -867,9 +811,9 @@ namespace thermion_filament
|
||||
///
|
||||
///
|
||||
///
|
||||
void FilamentViewer::setMainCamera()
|
||||
void FilamentViewer::setMainCamera(View *view)
|
||||
{
|
||||
_view->setCamera(_mainCamera);
|
||||
view->setCamera(_mainCamera);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -880,73 +824,6 @@ namespace thermion_filament
|
||||
return Entity::smuggle(_mainCamera->getEntity());
|
||||
}
|
||||
|
||||
///
|
||||
/// Sets the active camera to the GLTF camera node specified by [name] (or if null, the first camera found under that node).
|
||||
/// N.B. Blender will generally export a three-node hierarchy -
|
||||
/// Camera1->Camera_Orientation->Camera2. The correct name will be the Camera_Orientation.
|
||||
///
|
||||
bool FilamentViewer::setCamera(EntityId entityId, const char *cameraName)
|
||||
{
|
||||
|
||||
auto asset = _sceneManager->getAssetByEntityId(entityId);
|
||||
if (!asset)
|
||||
{
|
||||
Log("Failed to find asset under entity id %d.", entityId);
|
||||
return false;
|
||||
}
|
||||
size_t count = asset->getCameraEntityCount();
|
||||
if (count == 0)
|
||||
{
|
||||
Log("No cameras found attached to specified entity.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const utils::Entity *cameras = asset->getCameraEntities();
|
||||
|
||||
utils::Entity target;
|
||||
|
||||
if (!cameraName)
|
||||
{
|
||||
target = cameras[0];
|
||||
const char *name = asset->getName(target);
|
||||
Log("No camera specified, using first camera node found (%s)", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
const char *name = asset->getName(cameras[j]);
|
||||
if (strcmp(name, cameraName) == 0)
|
||||
{
|
||||
target = cameras[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target.isNull())
|
||||
{
|
||||
Log("Unable to locate camera under name %s ", cameraName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Camera *camera = _engine->getCameraComponent(target);
|
||||
if (!camera)
|
||||
{
|
||||
Log("Failed to retrieve camera component for target");
|
||||
return false;
|
||||
}
|
||||
_view->setCamera(camera);
|
||||
|
||||
const Viewport &vp = _view->getViewport();
|
||||
const double aspect = (double)vp.width / vp.height;
|
||||
|
||||
camera->setScaling({1.0 / aspect, 1.0});
|
||||
|
||||
Log("Successfully set view camera to target");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilamentViewer::loadSkybox(const char *const skyboxPath)
|
||||
{
|
||||
|
||||
@@ -990,8 +867,8 @@ namespace thermion_filament
|
||||
callbackData);
|
||||
_skybox =
|
||||
filament::Skybox::Builder()
|
||||
.environment(_skyboxTexture)
|
||||
.build(*_engine);
|
||||
.environment(_skyboxTexture)
|
||||
.build(*_engine);
|
||||
|
||||
_skybox->setLayerMask(0xFF, 1u << SceneManager::LAYERS::BACKGROUND);
|
||||
|
||||
@@ -1046,13 +923,25 @@ namespace thermion_filament
|
||||
|
||||
.build(*_engine);
|
||||
// Create a copy of the cubemap data
|
||||
float *pixelData = new float[18] {
|
||||
r, g, b,
|
||||
r, g, b,
|
||||
r, g, b,
|
||||
r, g, b,
|
||||
r, g, b,
|
||||
r, g, b,
|
||||
float *pixelData = new float[18]{
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
};
|
||||
|
||||
Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t, void *data)
|
||||
@@ -1126,13 +1015,14 @@ namespace thermion_filament
|
||||
|
||||
bool FilamentViewer::render(
|
||||
uint64_t frameTimeInNanos,
|
||||
SwapChain* swapChain,
|
||||
View *view,
|
||||
SwapChain *swapChain,
|
||||
void *pixelBuffer,
|
||||
void (*callback)(void *buf, size_t size, void *data),
|
||||
void *data)
|
||||
{
|
||||
|
||||
if (!_view || !swapChain)
|
||||
if (!view || !swapChain)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1155,15 +1045,6 @@ namespace thermion_filament
|
||||
|
||||
_cumulativeAnimationUpdateTime += tmr.elapsed();
|
||||
|
||||
// if a manipulator is active, update the active camera orientation
|
||||
if (_manipulator)
|
||||
{
|
||||
math::double3 eye, target, upward;
|
||||
Camera &cam = _view->getCamera();
|
||||
_manipulator->getLookAt(&eye, &target, &upward);
|
||||
cam.lookAt(eye, target, upward);
|
||||
}
|
||||
|
||||
// Render the scene, unless the renderer wants to skip the frame.
|
||||
bool beginFrame = _renderer->beginFrame(swapChain, frameTimeInNanos);
|
||||
if (!beginFrame)
|
||||
@@ -1174,7 +1055,7 @@ namespace thermion_filament
|
||||
if (beginFrame)
|
||||
{
|
||||
|
||||
_renderer->render(_view);
|
||||
_renderer->render(view);
|
||||
|
||||
_frameCount++;
|
||||
|
||||
@@ -1186,21 +1067,24 @@ namespace thermion_filament
|
||||
return beginFrame;
|
||||
}
|
||||
|
||||
class CaptureCallbackHandler : public filament::backend::CallbackHandler {
|
||||
void post(void* user, Callback callback) {
|
||||
callback(user);
|
||||
}
|
||||
class CaptureCallbackHandler : public filament::backend::CallbackHandler
|
||||
{
|
||||
void post(void *user, Callback callback)
|
||||
{
|
||||
callback(user);
|
||||
}
|
||||
};
|
||||
|
||||
void FilamentViewer::capture(uint8_t *out, bool useFence, SwapChain* swapChain, void (*onComplete)())
|
||||
void FilamentViewer::capture(View *view, uint8_t *out, bool useFence, SwapChain *swapChain, void (*onComplete)())
|
||||
{
|
||||
|
||||
if(!swapChain) {
|
||||
if (!swapChain)
|
||||
{
|
||||
Log("NO SWAPCHAIN");
|
||||
return;
|
||||
}
|
||||
|
||||
Viewport const &vp = _view->getViewport();
|
||||
Viewport const &vp = view->getViewport();
|
||||
size_t pixelBufferSize = vp.width * vp.height * 4;
|
||||
auto *pixelBuffer = new uint8_t[pixelBufferSize];
|
||||
auto callback = [](void *buf, size_t size, void *data)
|
||||
@@ -1211,15 +1095,17 @@ namespace thermion_filament
|
||||
|
||||
memcpy(out, buf, size);
|
||||
delete frameCallbackData;
|
||||
if(callbackPtr) {
|
||||
if (callbackPtr)
|
||||
{
|
||||
void (*callback)(void) = (void (*)(void))callbackPtr;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
// Create a fence
|
||||
Fence* fence = nullptr;
|
||||
if(useFence) {
|
||||
Fence *fence = nullptr;
|
||||
if (useFence)
|
||||
{
|
||||
fence = _engine->createFence();
|
||||
}
|
||||
|
||||
@@ -1232,7 +1118,7 @@ namespace thermion_filament
|
||||
Texture::Format::RGBA,
|
||||
Texture::Type::UBYTE, dispatcher, callback, userData);
|
||||
_renderer->beginFrame(swapChain, 0);
|
||||
_renderer->render(_view);
|
||||
_renderer->render(view);
|
||||
_renderer->readPixels(0, 0, vp.width, vp.height, std::move(pbd));
|
||||
_renderer->endFrame();
|
||||
|
||||
@@ -1240,20 +1126,22 @@ namespace thermion_filament
|
||||
_engine->execute();
|
||||
emscripten_webgl_commit_frame();
|
||||
#endif
|
||||
if(fence) {
|
||||
Fence::waitAndDestroy(fence);
|
||||
}
|
||||
if (fence)
|
||||
{
|
||||
Fence::waitAndDestroy(fence);
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentViewer::capture(uint8_t *out, bool useFence, SwapChain* swapChain, RenderTarget* renderTarget, void (*onComplete)())
|
||||
void FilamentViewer::capture(View *view, uint8_t *out, bool useFence, SwapChain *swapChain, RenderTarget *renderTarget, void (*onComplete)())
|
||||
{
|
||||
|
||||
if(!renderTarget) {
|
||||
if (!renderTarget)
|
||||
{
|
||||
Log("NO SWAPCHAIN");
|
||||
return;
|
||||
}
|
||||
|
||||
Viewport const &vp = _view->getViewport();
|
||||
Viewport const &vp = view->getViewport();
|
||||
size_t pixelBufferSize = vp.width * vp.height * 4;
|
||||
auto *pixelBuffer = new uint8_t[pixelBufferSize];
|
||||
auto callback = [](void *buf, size_t size, void *data)
|
||||
@@ -1264,15 +1152,17 @@ namespace thermion_filament
|
||||
|
||||
memcpy(out, buf, size);
|
||||
delete frameCallbackData;
|
||||
if(callbackPtr) {
|
||||
if (callbackPtr)
|
||||
{
|
||||
void (*callback)(void) = (void (*)(void))callbackPtr;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
// Create a fence
|
||||
Fence* fence = nullptr;
|
||||
if(useFence) {
|
||||
Fence *fence = nullptr;
|
||||
if (useFence)
|
||||
{
|
||||
fence = _engine->createFence();
|
||||
}
|
||||
|
||||
@@ -1285,7 +1175,7 @@ namespace thermion_filament
|
||||
Texture::Format::RGBA,
|
||||
Texture::Type::UBYTE, dispatcher, callback, userData);
|
||||
_renderer->beginFrame(swapChain, 0);
|
||||
_renderer->render(_view);
|
||||
_renderer->render(view);
|
||||
_renderer->readPixels(renderTarget, 0, 0, vp.width, vp.height, std::move(pbd));
|
||||
_renderer->endFrame();
|
||||
|
||||
@@ -1293,138 +1183,22 @@ namespace thermion_filament
|
||||
_engine->execute();
|
||||
emscripten_webgl_commit_frame();
|
||||
#endif
|
||||
if(fence) {
|
||||
Fence::waitAndDestroy(fence);
|
||||
}
|
||||
if (fence)
|
||||
{
|
||||
Fence::waitAndDestroy(fence);
|
||||
}
|
||||
}
|
||||
|
||||
Camera* FilamentViewer::getCamera(EntityId entity) {
|
||||
Camera *FilamentViewer::getCamera(EntityId entity)
|
||||
{
|
||||
return _engine->getCameraComponent(Entity::import(entity));
|
||||
}
|
||||
|
||||
void FilamentViewer::updateViewport(
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
_view->setViewport({0, 0, width, height});
|
||||
}
|
||||
|
||||
void FilamentViewer::setViewFrustumCulling(bool enabled)
|
||||
{
|
||||
_view->setFrustumCullingEnabled(enabled);
|
||||
}
|
||||
|
||||
void FilamentViewer::_createManipulator()
|
||||
{
|
||||
Camera &cam = _view->getCamera();
|
||||
|
||||
math::double3 home = cam.getPosition();
|
||||
math::double3 up = cam.getUpVector();
|
||||
auto fv = cam.getForwardVector();
|
||||
math::double3 target = home + fv;
|
||||
Viewport const &vp = _view->getViewport();
|
||||
|
||||
_manipulator = Manipulator<double>::Builder()
|
||||
.viewport(vp.width, vp.height)
|
||||
.upVector(up.x, up.y, up.z)
|
||||
.zoomSpeed(_zoomSpeed)
|
||||
.targetPosition(target[0], target[1], target[2])
|
||||
// only applicable to Mode::ORBIT
|
||||
.orbitHomePosition(home[0], home[1], home[2])
|
||||
.orbitSpeed(_orbitSpeedX, _orbitSpeedY)
|
||||
// only applicable to Mode::FREE_FLIGHT
|
||||
.flightStartPosition(home[0], home[1], home[2])
|
||||
.build(_manipulatorMode);
|
||||
}
|
||||
|
||||
void FilamentViewer::setCameraManipulatorOptions(filament::camutils::Mode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed)
|
||||
{
|
||||
_manipulatorMode = mode;
|
||||
_orbitSpeedX = orbitSpeedX;
|
||||
_orbitSpeedY = orbitSpeedY;
|
||||
_zoomSpeed = zoomSpeed;
|
||||
}
|
||||
|
||||
void FilamentViewer::grabBegin(float x, float y, bool pan)
|
||||
{
|
||||
if (!_view || !_mainCamera)
|
||||
{
|
||||
Log("View not ready, ignoring grab");
|
||||
return;
|
||||
}
|
||||
if (!_manipulator)
|
||||
{
|
||||
_createManipulator();
|
||||
}
|
||||
_manipulator->grabBegin(x, y, pan);
|
||||
}
|
||||
|
||||
void FilamentViewer::grabUpdate(float x, float y)
|
||||
{
|
||||
if (!_view )
|
||||
{
|
||||
Log("View not ready, ignoring grab");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_manipulator)
|
||||
{
|
||||
_manipulator->grabUpdate(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentViewer::grabEnd()
|
||||
{
|
||||
if (!_view || !_mainCamera )
|
||||
{
|
||||
Log("View not ready, ignoring grab");
|
||||
return;
|
||||
}
|
||||
if (_manipulator)
|
||||
{
|
||||
_manipulator->grabEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
|
||||
}
|
||||
delete _manipulator;
|
||||
_manipulator = nullptr;
|
||||
}
|
||||
|
||||
void FilamentViewer::scrollBegin()
|
||||
{
|
||||
if (!_manipulator)
|
||||
{
|
||||
_createManipulator();
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentViewer::scrollUpdate(float x, float y, float delta)
|
||||
{
|
||||
if (_manipulator)
|
||||
{
|
||||
_manipulator->scroll(int(x), int(y), delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentViewer::scrollEnd()
|
||||
{
|
||||
delete _manipulator;
|
||||
_manipulator = nullptr;
|
||||
}
|
||||
|
||||
void FilamentViewer::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||
void FilamentViewer::pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||
{
|
||||
|
||||
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
|
||||
view->pick(x, y, [=](filament::View::PickingQueryResult const &result)
|
||||
{
|
||||
|
||||
if(_sceneManager->gizmo->isGizmoEntity(result.renderable)) {
|
||||
Log("Gizmo entity, ignoring");
|
||||
@@ -1438,24 +1212,23 @@ namespace thermion_filament
|
||||
|
||||
if (nonPickableEntities.find(result.renderable) == nonPickableEntities.end()) {
|
||||
callback(Entity::smuggle(result.renderable), x, y);
|
||||
}
|
||||
});
|
||||
} });
|
||||
}
|
||||
|
||||
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t* out, uint32_t outWidth, uint32_t outHeight) {
|
||||
const auto * geometry = _sceneManager->getGeometry(entityId);
|
||||
if(!geometry->uvs) {
|
||||
Log("No UVS");
|
||||
return;
|
||||
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
||||
{
|
||||
const auto *geometry = _sceneManager->getGeometry(entityId);
|
||||
if (!geometry->uvs)
|
||||
{
|
||||
Log("No UVS");
|
||||
return;
|
||||
}
|
||||
|
||||
UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
|
||||
|
||||
// UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
|
||||
|
||||
// TODO - check that input dimensions match viewport?
|
||||
|
||||
unproject.unproject(utils::Entity::import(entityId), input, out, inputWidth, inputHeight, outWidth, outHeight);
|
||||
|
||||
// unproject.unproject(utils::Entity::import(entityId), input, out, inputWidth, inputHeight, outWidth, outHeight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace thermion_filament
|
||||
|
||||
@@ -14,12 +14,10 @@ namespace thermion_filament {
|
||||
|
||||
using namespace filament::gltfio;
|
||||
|
||||
Gizmo::Gizmo(Engine &engine, View* view, Scene* scene) : _engine(engine)
|
||||
Gizmo::Gizmo(Engine &engine, Scene* scene) : _engine(engine)
|
||||
{
|
||||
|
||||
_scene = scene;
|
||||
_view = view;
|
||||
_camera = &(_view->getCamera());
|
||||
|
||||
auto &entityManager = EntityManager::get();
|
||||
|
||||
@@ -326,10 +324,10 @@ void Gizmo::unhighlight() {
|
||||
}
|
||||
}
|
||||
|
||||
void Gizmo::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||
void Gizmo::pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||
{
|
||||
auto handler = new Gizmo::PickCallbackHandler(this, callback);
|
||||
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
|
||||
view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
|
||||
handler->handle(result);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,13 +48,12 @@ namespace thermion_filament
|
||||
using namespace filament::gltfio;
|
||||
using std::unique_ptr;
|
||||
|
||||
SceneManager::SceneManager(View *view,
|
||||
const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
|
||||
SceneManager::SceneManager(const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
|
||||
Engine *engine,
|
||||
Scene *scene,
|
||||
const char *uberArchivePath,
|
||||
Camera *mainCamera)
|
||||
: _view(view),
|
||||
:
|
||||
_resourceLoaderWrapper(resourceLoaderWrapper),
|
||||
_engine(engine),
|
||||
_scene(scene),
|
||||
@@ -99,21 +98,16 @@ namespace thermion_filament
|
||||
_collisionComponentManager = new CollisionComponentManager(tm);
|
||||
_animationComponentManager = new AnimationComponentManager(tm, _engine->getRenderableManager());
|
||||
|
||||
gizmo = new Gizmo(*_engine, _view, _scene);
|
||||
gizmo = new Gizmo(*_engine, _scene);
|
||||
_gridOverlay = new GridOverlay(*_engine);
|
||||
|
||||
_scene->addEntity(_gridOverlay->sphere());
|
||||
_scene->addEntity(_gridOverlay->grid());
|
||||
|
||||
_view->setLayerEnabled(SceneManager::LAYERS::DEFAULT_ASSETS, true);
|
||||
_view->setLayerEnabled(SceneManager::LAYERS::BACKGROUND, true); // skybox + image
|
||||
_view->setLayerEnabled(SceneManager::LAYERS::OVERLAY, false); // world grid + gizmo
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager()
|
||||
{
|
||||
_view->setScene(nullptr);
|
||||
_view->setCamera(nullptr);
|
||||
for(auto camera : _cameras) {
|
||||
auto entity = camera->getEntity();
|
||||
_engine->destroyCameraComponent(entity);
|
||||
@@ -1894,11 +1888,11 @@ namespace thermion_filament
|
||||
tm.setTransform(transformInstance, newTransform);
|
||||
}
|
||||
|
||||
void SceneManager::queueRelativePositionUpdateFromViewportVector(EntityId entityId, float viewportCoordX, float viewportCoordY)
|
||||
void SceneManager::queueRelativePositionUpdateFromViewportVector(View* view, EntityId entityId, float viewportCoordX, float viewportCoordY)
|
||||
{
|
||||
// Get the camera and viewport
|
||||
const auto &camera = _view->getCamera();
|
||||
const auto &vp = _view->getViewport();
|
||||
const auto &camera = view->getCamera();
|
||||
const auto &vp = view->getViewport();
|
||||
|
||||
// Convert viewport coordinates to NDC space
|
||||
float ndcX = (2.0f * viewportCoordX) / vp.width - 1.0f;
|
||||
@@ -2170,10 +2164,10 @@ namespace thermion_filament
|
||||
rm.setPriority(renderableInstance, priority);
|
||||
}
|
||||
|
||||
Aabb2 SceneManager::getBoundingBox(EntityId entityId)
|
||||
Aabb2 SceneManager::getBoundingBox(View *view, EntityId entityId)
|
||||
{
|
||||
const auto &camera = _view->getCamera();
|
||||
const auto &viewport = _view->getViewport();
|
||||
const auto &camera = view->getCamera();
|
||||
const auto &viewport = view->getViewport();
|
||||
|
||||
auto &tcm = _engine->getTransformManager();
|
||||
auto &rcm = _engine->getRenderableManager();
|
||||
@@ -2242,11 +2236,6 @@ namespace thermion_filament
|
||||
return Aabb2{minX, minY, maxX, maxY};
|
||||
}
|
||||
|
||||
void SceneManager::setLayerVisibility(LAYERS layer, bool enabled)
|
||||
{
|
||||
_view->setLayerEnabled(layer, enabled);
|
||||
}
|
||||
|
||||
void SceneManager::removeStencilHighlight(EntityId entityId)
|
||||
{
|
||||
std::lock_guard lock(_stencilMutex);
|
||||
@@ -2491,10 +2480,6 @@ EntityId SceneManager::createGeometry(
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::setCamera(Camera* camera) {
|
||||
_view->setCamera(camera);
|
||||
}
|
||||
|
||||
size_t SceneManager::getCameraCount() {
|
||||
return _cameras.size() + 1;
|
||||
}
|
||||
@@ -2508,11 +2493,6 @@ EntityId SceneManager::createGeometry(
|
||||
}
|
||||
return _cameras[index-1];
|
||||
}
|
||||
|
||||
Camera* SceneManager::getActiveCamera() {
|
||||
auto& camera = _view->getCamera();
|
||||
return &camera;
|
||||
}
|
||||
|
||||
|
||||
} // namespace thermion_filament
|
||||
|
||||
29
thermion_dart/native/src/TGizmo.cpp
Normal file
29
thermion_dart/native/src/TGizmo.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
#endif
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "FilamentViewer.hpp"
|
||||
#include "filament/LightManager.h"
|
||||
#include "Log.hpp"
|
||||
#include "ThreadPool.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
using namespace thermion_filament;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, TView *tView, int x, int y, void (*callback)(EntityId entityId, int x, int y))
|
||||
{
|
||||
auto *gizmo = reinterpret_cast<Gizmo*>(tGizmo);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
gizmo->pick(view, x, y, callback);
|
||||
}
|
||||
}
|
||||
142
thermion_dart/native/src/TView.cpp
Normal file
142
thermion_dart/native/src/TView.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
#endif
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "FilamentViewer.hpp"
|
||||
#include "filament/LightManager.h"
|
||||
#include "Log.hpp"
|
||||
#include "ThreadPool.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
using namespace thermion_filament;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_updateViewport(TView *tView, uint32_t width, uint32_t height)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
view->setViewport({0, 0, width, height});
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setRenderTarget(TView *tView, TRenderTarget *tRenderTarget)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
auto renderTarget = reinterpret_cast<RenderTarget *>(tRenderTarget);
|
||||
view->setRenderTarget(renderTarget);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setFrustumCullingEnabled(TView *tView, bool enabled)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
view->setFrustumCullingEnabled(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setPostProcessing(TView *tView, bool enabled)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
view->setPostProcessingEnabled(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setShadowsEnabled(TView *tView, bool enabled)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
view->setShadowingEnabled(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setShadowType(TView *tView, ShadowType shadowType)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
view->setShadowType(shadowType);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setSoftShadowOptions(TView *tView, float penumbraScale, float penumbraRatioScale)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
SoftShadowOptions opts;
|
||||
opts.penumbraRatioScale = penumbraRatioScale;
|
||||
opts.penumbraScale = penumbraScale;
|
||||
view->setSoftShadowOptions(opts);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setBloom(TView *tView, float strength)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
#ifndef __EMSCRIPTEN__
|
||||
decltype(view->getBloomOptions()) opts;
|
||||
opts.enabled = true;
|
||||
opts.strength = strength;
|
||||
view->setBloomOptions(opts);
|
||||
#endif
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setToneMapping(TView *tView, TEngine *tEngine, int toneMapping)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
auto engine = reinterpret_cast<Engine *>(tEngine);
|
||||
|
||||
ToneMapper *tm;
|
||||
switch (toneMapping)
|
||||
{
|
||||
case ToneMapping::ACES:
|
||||
Log("Setting tone mapping to ACES");
|
||||
tm = new ACESToneMapper();
|
||||
break;
|
||||
case ToneMapping::LINEAR:
|
||||
Log("Setting tone mapping to Linear");
|
||||
tm = new LinearToneMapper();
|
||||
break;
|
||||
case ToneMapping::FILMIC:
|
||||
Log("Setting tone mapping to Filmic");
|
||||
tm = new FilmicToneMapper();
|
||||
break;
|
||||
default:
|
||||
Log("ERROR: Unsupported tone mapping");
|
||||
return;
|
||||
}
|
||||
auto newColorGrading = ColorGrading::Builder().toneMapper(tm).build(*engine);
|
||||
auto oldColorGrading = view->getColorGrading();
|
||||
view->setColorGrading(newColorGrading);
|
||||
|
||||
if (oldColorGrading)
|
||||
{
|
||||
engine->destroy(oldColorGrading);
|
||||
}
|
||||
delete tm;
|
||||
}
|
||||
|
||||
void View_setAntiAliasing(TView *tView, bool msaa, bool fxaa, bool taa)
|
||||
{
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
View::MultiSampleAntiAliasingOptions multiSampleAntiAliasingOptions;
|
||||
multiSampleAntiAliasingOptions.enabled = msaa;
|
||||
|
||||
view->setMultiSampleAntiAliasingOptions(multiSampleAntiAliasingOptions);
|
||||
TemporalAntiAliasingOptions taaOpts;
|
||||
taaOpts.enabled = taa;
|
||||
view->setTemporalAntiAliasingOptions(taaOpts);
|
||||
view->setAntiAliasing(fxaa ? AntiAliasing::FXAA : AntiAliasing::NONE);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setLayerEnabled(TView* tView, int layer, bool enabled) {
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
view->setLayerEnabled(layer, enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setCamera(TView *tView, TCamera *tCamera) {
|
||||
auto view = reinterpret_cast<View *>(tView);
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
view->setCamera(camera);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,32 +48,28 @@ extern "C"
|
||||
{
|
||||
const auto *loaderImpl = new ResourceLoaderWrapperImpl((ResourceLoaderWrapper *)loader);
|
||||
auto viewer = new FilamentViewer(context, loaderImpl, platform, uberArchivePath);
|
||||
return reinterpret_cast<TViewer*>(viewer);
|
||||
return reinterpret_cast<TViewer *>(viewer);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer) {
|
||||
auto* engine = reinterpret_cast<FilamentViewer*>(viewer)->getEngine();
|
||||
return reinterpret_cast<TEngine*>(engine);
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer *viewer)
|
||||
{
|
||||
auto *engine = reinterpret_cast<FilamentViewer *>(viewer)->getEngine();
|
||||
return reinterpret_cast<TEngine *>(engine);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *tViewer, intptr_t texture, uint32_t width, uint32_t height)
|
||||
EMSCRIPTEN_KEEPALIVE TRenderTarget *Viewer_createRenderTarget(TViewer *tViewer, intptr_t texture, uint32_t width, uint32_t height)
|
||||
{
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto renderTarget = viewer->createRenderTarget(texture, width, height);
|
||||
return reinterpret_cast<TRenderTarget*>(renderTarget);
|
||||
return reinterpret_cast<TRenderTarget *>(renderTarget);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *tViewer, TRenderTarget* tRenderTarget) {
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *tViewer, TRenderTarget *tRenderTarget)
|
||||
{
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto renderTarget = reinterpret_cast<RenderTarget*>(tRenderTarget);
|
||||
auto renderTarget = reinterpret_cast<RenderTarget *>(tRenderTarget);
|
||||
viewer->destroyRenderTarget(renderTarget);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setRenderTarget(TViewer *tViewer, TRenderTarget* tRenderTarget) {
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto renderTarget = reinterpret_cast<RenderTarget*>(tRenderTarget);
|
||||
viewer->setRenderTarget(renderTarget);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer)
|
||||
{
|
||||
@@ -92,23 +88,14 @@ extern "C"
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image(TViewer *viewer, const char *path, bool fillHeight)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setBackgroundImage(path, fillHeight);
|
||||
((FilamentViewer *)viewer)->setBackgroundImage(path, fillHeight, 100, 100);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image_position(TViewer *viewer, float x, float y, bool clamp)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setBackgroundImagePosition(x, y, clamp);
|
||||
((FilamentViewer *)viewer)->setBackgroundImagePosition(x, y, clamp, 100, 100);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_tone_mapping(TViewer *viewer, int toneMapping)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setToneMapping((ToneMapping)toneMapping);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_bloom(TViewer *viewer, float strength)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setBloom(strength);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath)
|
||||
{
|
||||
@@ -221,9 +208,11 @@ extern "C"
|
||||
return ((SceneManager *)sceneManager)->loadGltf(assetPath, relativePath, keepData);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_main_camera(TViewer *viewer)
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView)
|
||||
{
|
||||
return ((FilamentViewer *)viewer)->setMainCamera();
|
||||
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
viewer->setMainCamera(view);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer)
|
||||
@@ -231,11 +220,6 @@ extern "C"
|
||||
return ((FilamentViewer *)viewer)->getMainCamera();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool set_camera(TViewer *viewer, EntityId asset, const char *nodeName)
|
||||
{
|
||||
return ((FilamentViewer *)viewer)->setCamera(asset, nodeName);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal)
|
||||
{
|
||||
auto cam = reinterpret_cast<filament::Camera *>(camera);
|
||||
@@ -334,15 +318,7 @@ extern "C"
|
||||
return array;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_manipulator_options(TViewer *viewer, _ManipulatorMode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setCameraManipulatorOptions((filament::camutils::Mode)mode, orbitSpeedX, orbitSpeedY, zoomSpeed);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setViewFrustumCulling(enabled);
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float distance)
|
||||
{
|
||||
@@ -365,20 +341,23 @@ extern "C"
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool Viewer_render(
|
||||
TViewer *tViewer,
|
||||
TView *tView,
|
||||
TSwapChain *tSwapChain,
|
||||
uint64_t frameTimeInNanos,
|
||||
void *pixelBuffer,
|
||||
void (*callback)(void *buf, size_t size, void *data),
|
||||
void *data)
|
||||
{
|
||||
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
|
||||
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
return viewer->render(frameTimeInNanos, swapChain, pixelBuffer, callback, data);
|
||||
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
return viewer->render(frameTimeInNanos, view, swapChain, pixelBuffer, callback, data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
|
||||
TViewer *tViewer,
|
||||
TSwapChain* tSwapChain,
|
||||
TView *tView,
|
||||
TSwapChain *tSwapChain,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void))
|
||||
{
|
||||
@@ -387,14 +366,16 @@ extern "C"
|
||||
#else
|
||||
bool useFence = false;
|
||||
#endif
|
||||
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
|
||||
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
viewer->capture(pixelBuffer, useFence, swapChain, callback);
|
||||
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
viewer->capture(view, pixelBuffer, useFence, swapChain, callback);
|
||||
};
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget(
|
||||
TViewer *tViewer,
|
||||
TSwapChain* tSwapChain,
|
||||
TView *tView,
|
||||
TSwapChain *tSwapChain,
|
||||
TRenderTarget *tRenderTarget,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void))
|
||||
@@ -404,10 +385,11 @@ extern "C"
|
||||
#else
|
||||
bool useFence = false;
|
||||
#endif
|
||||
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
|
||||
auto renderTarget = reinterpret_cast<RenderTarget*>(tRenderTarget);
|
||||
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
viewer->capture(pixelBuffer, useFence, swapChain, renderTarget, callback);
|
||||
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
|
||||
auto renderTarget = reinterpret_cast<RenderTarget *>(tRenderTarget);
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
viewer->capture(view, pixelBuffer, useFence, swapChain, renderTarget, callback);
|
||||
};
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_frame_interval(
|
||||
@@ -417,59 +399,41 @@ extern "C"
|
||||
((FilamentViewer *)viewer)->setFrameInterval(frameInterval);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *tViewer, TSwapChain* tSwapChain)
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *tViewer, TSwapChain *tSwapChain)
|
||||
{
|
||||
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
|
||||
viewer->destroySwapChain(swapChain);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *tViewer, const void *const window, uint32_t width, uint32_t height) {
|
||||
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *tViewer, const void *const window, uint32_t width, uint32_t height)
|
||||
{
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto swapChain = viewer->createSwapChain(window, width, height);
|
||||
return reinterpret_cast<TSwapChain*>(swapChain);
|
||||
return reinterpret_cast<TSwapChain *>(swapChain);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void update_viewport(TViewer *viewer, uint32_t width, uint32_t height)
|
||||
EMSCRIPTEN_KEEPALIVE TView *Viewer_createView(TViewer *tViewer)
|
||||
{
|
||||
return ((FilamentViewer *)viewer)->updateViewport(width, height);
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto view = viewer->createView();
|
||||
return reinterpret_cast<TView *>(view);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_update(TViewer *viewer, float x, float y, float delta)
|
||||
EMSCRIPTEN_KEEPALIVE TView *Viewer_getViewAt(TViewer *tViewer, int32_t index)
|
||||
{
|
||||
((FilamentViewer *)viewer)->scrollUpdate(x, y, delta);
|
||||
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto view = viewer->getViewAt(index);
|
||||
return reinterpret_cast<TView *>(view);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_begin(TViewer *viewer)
|
||||
{
|
||||
((FilamentViewer *)viewer)->scrollBegin();
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_end(TViewer *viewer)
|
||||
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *tViewer)
|
||||
{
|
||||
((FilamentViewer *)viewer)->scrollEnd();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void grab_begin(TViewer *viewer, float x, float y, bool pan)
|
||||
{
|
||||
((FilamentViewer *)viewer)->grabBegin(x, y, pan);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void grab_update(TViewer *viewer, float x, float y)
|
||||
{
|
||||
((FilamentViewer *)viewer)->grabUpdate(x, y);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void grab_end(TViewer *viewer)
|
||||
{
|
||||
((FilamentViewer *)viewer)->grabEnd();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TSceneManager* Viewer_getSceneManager(TViewer *tViewer)
|
||||
{
|
||||
auto * viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
auto * sceneManager = viewer->getSceneManager();
|
||||
return reinterpret_cast<TSceneManager*>(sceneManager);
|
||||
auto *viewer = reinterpret_cast<FilamentViewer *>(tViewer);
|
||||
auto *sceneManager = viewer->getSceneManager();
|
||||
return reinterpret_cast<TSceneManager *>(sceneManager);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void apply_weights(
|
||||
@@ -529,31 +493,6 @@ extern "C"
|
||||
((SceneManager *)sceneManager)->addBoneAnimation(asset, skinIndex, boneIndex, frameData, numFrames, frameLengthInMs, fadeOutInSecs, fadeInInSecs, maxDelta);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_post_processing(TViewer *viewer, bool enabled)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setPostProcessing(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_shadows_enabled(TViewer *viewer, bool enabled)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setShadowsEnabled(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_shadow_type(TViewer *viewer, int shadowType)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setShadowType((ShadowType)shadowType);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_soft_shadow_options(TViewer *viewer, float penumbraScale, float penumbraRatioScale)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setSoftShadowOptions(penumbraScale, penumbraRatioScale);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_antialiasing(TViewer *viewer, bool msaa, bool fxaa, bool taa)
|
||||
{
|
||||
((FilamentViewer *)viewer)->setAntiAliasing(msaa, fxaa, taa);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_bone(TSceneManager *sceneManager,
|
||||
EntityId entityId,
|
||||
int skinIndex,
|
||||
@@ -737,6 +676,17 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraByName(TSceneManager *tSceneManager, EntityId entityId, const char* name) {
|
||||
auto *sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TGizmo* SceneManager_getGizmo(TSceneManager *tSceneManager) {
|
||||
auto *sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
auto *gizmo = sceneManager->gizmo;
|
||||
return reinterpret_cast<TGizmo*>(gizmo);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setTransform(TSceneManager *sceneManager, EntityId entityId, const double *const transform)
|
||||
{
|
||||
auto matrix = math::mat4(
|
||||
@@ -757,25 +707,27 @@ extern "C"
|
||||
return ((SceneManager *)sceneManager)->setTransform(entityId, matrix);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *tSceneManager, EntityId* entities, const double* const transforms, int numEntities) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *tSceneManager, EntityId *entities, const double *const transforms, int numEntities)
|
||||
{
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
math::mat4 matrices[numEntities];
|
||||
for(int i = 0; i < numEntities; i++) {
|
||||
matrices[i] = math::mat4(
|
||||
transforms[i * 16], transforms[i*16+1], transforms[i*16+2],
|
||||
transforms[i*16+3],
|
||||
transforms[i*16+4],
|
||||
transforms[i*16+5],
|
||||
transforms[i*16+6],
|
||||
transforms[i*16+7],
|
||||
transforms[i*16+8],
|
||||
transforms[i*16+9],
|
||||
transforms[i*16+10],
|
||||
transforms[i*16+11],
|
||||
transforms[i*16+12],
|
||||
transforms[i*16+13],
|
||||
transforms[i*16+14],
|
||||
transforms[i*16+15]);
|
||||
for (int i = 0; i < numEntities; i++)
|
||||
{
|
||||
matrices[i] = math::mat4(
|
||||
transforms[i * 16], transforms[i * 16 + 1], transforms[i * 16 + 2],
|
||||
transforms[i * 16 + 3],
|
||||
transforms[i * 16 + 4],
|
||||
transforms[i * 16 + 5],
|
||||
transforms[i * 16 + 6],
|
||||
transforms[i * 16 + 7],
|
||||
transforms[i * 16 + 8],
|
||||
transforms[i * 16 + 9],
|
||||
transforms[i * 16 + 10],
|
||||
transforms[i * 16 + 11],
|
||||
transforms[i * 16 + 12],
|
||||
transforms[i * 16 + 13],
|
||||
transforms[i * 16 + 14],
|
||||
transforms[i * 16 + 15]);
|
||||
}
|
||||
sceneManager->queueTransformUpdates(entities, matrices, numEntities);
|
||||
}
|
||||
@@ -833,9 +785,10 @@ extern "C"
|
||||
((SceneManager *)sceneManager)->setScale(asset, scale);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY)
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, TView *tView, EntityId entity, float viewportX, float viewportY)
|
||||
{
|
||||
((SceneManager *)sceneManager)->queueRelativePositionUpdateFromViewportVector(entity, viewportX, viewportY);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
((SceneManager *)sceneManager)->queueRelativePositionUpdateFromViewportVector(view, entity, viewportX, viewportY);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void stop_animation(TSceneManager *sceneManager, EntityId asset, int index)
|
||||
@@ -853,9 +806,11 @@ extern "C"
|
||||
return ((SceneManager *)sceneManager)->reveal(asset, meshName);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *viewer, int x, int y, void (*callback)(EntityId entityId, int x, int y))
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *tViewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y))
|
||||
{
|
||||
((FilamentViewer *)viewer)->pick(static_cast<uint32_t>(x), static_cast<uint32_t>(y), callback);
|
||||
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
|
||||
auto *view = reinterpret_cast<View*>(tView);
|
||||
((FilamentViewer *)viewer)->pick(view, static_cast<uint32_t>(x), static_cast<uint32_t>(y), callback);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId)
|
||||
@@ -965,28 +920,26 @@ extern "C"
|
||||
out[3] = Entity::smuggle(gizmo->center());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, EntityId entity)
|
||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *tView, EntityId entity)
|
||||
{
|
||||
return ((SceneManager *)sceneManager)->getBoundingBox(entity);
|
||||
auto view = reinterpret_cast<View*>(tView);
|
||||
return ((SceneManager *)sceneManager)->getBoundingBox(view, entity);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, EntityId entity, float *minX, float *minY, float *maxX, float *maxY)
|
||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *tView, EntityId entity, float *minX, float *minY, float *maxX, float *maxY)
|
||||
{
|
||||
auto box = ((SceneManager *)sceneManager)->getBoundingBox(entity);
|
||||
auto view = reinterpret_cast<View*>(tView);
|
||||
auto box = ((SceneManager *)sceneManager)->getBoundingBox(view, entity);
|
||||
*minX = box.minX;
|
||||
*minY = box.minY;
|
||||
*maxX = box.maxX;
|
||||
*maxY = box.maxY;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_visibility_layer(TSceneManager *sceneManager, EntityId entity, int layer) {
|
||||
((SceneManager*)sceneManager)->setVisibilityLayer(entity, layer);
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_layer_visibility(TSceneManager *sceneManager, int layer, bool visible)
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer)
|
||||
{
|
||||
((SceneManager *)sceneManager)->setLayerVisibility((SceneManager::LAYERS)layer, visible);
|
||||
auto *sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
sceneManager->setVisibilityLayer(entity, layer);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void thermion_flutter_free(void *ptr)
|
||||
@@ -994,11 +947,6 @@ extern "C"
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void pick_gizmo(TSceneManager *sceneManager, int x, int y, void (*callback)(EntityId entityId, int x, int y))
|
||||
{
|
||||
((SceneManager *)sceneManager)->gizmo->pick(x, y, callback);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_gizmo_visibility(TSceneManager *sceneManager, bool visible)
|
||||
{
|
||||
((SceneManager *)sceneManager)->gizmo->setVisibility(visible);
|
||||
@@ -1019,9 +967,10 @@ extern "C"
|
||||
((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, value);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(TSceneManager *sceneManager, EntityId entity, int materialIndex) {
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *get_material_instance_at(TSceneManager *sceneManager, EntityId entity, int materialIndex)
|
||||
{
|
||||
auto instance = ((SceneManager *)sceneManager)->getMaterialInstanceAt(entity, materialIndex);
|
||||
return reinterpret_cast<TMaterialInstance*>(instance);
|
||||
return reinterpret_cast<TMaterialInstance *>(instance);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_int(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, int32_t value)
|
||||
@@ -1030,7 +979,7 @@ extern "C"
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_float4(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, double4 value)
|
||||
{
|
||||
{
|
||||
filament::math::float4 filamentValue;
|
||||
filamentValue.x = static_cast<float32_t>(value.x);
|
||||
filamentValue.y = static_cast<float32_t>(value.y);
|
||||
@@ -1039,7 +988,7 @@ extern "C"
|
||||
((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, filamentValue);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer *viewer, EntityId entity, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
||||
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer *viewer, EntityId entity, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
||||
{
|
||||
((FilamentViewer *)viewer)->unprojectTexture(entity, input, inputWidth, inputHeight, out, outWidth, outHeight);
|
||||
}
|
||||
@@ -1059,146 +1008,154 @@ extern "C"
|
||||
((SceneManager *)sceneManager)->destroyTexture(reinterpret_cast<Texture *>(texture));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig)
|
||||
{
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance* create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig)
|
||||
{
|
||||
filament::gltfio::MaterialKey config;
|
||||
memset(&config, 0, sizeof(MaterialKey));
|
||||
|
||||
filament::gltfio::MaterialKey config;
|
||||
memset(&config, 0, sizeof(MaterialKey));
|
||||
|
||||
// Set and log each field
|
||||
config.unlit = materialConfig.unlit;
|
||||
config.doubleSided = materialConfig.doubleSided;
|
||||
config.useSpecularGlossiness = materialConfig.useSpecularGlossiness;
|
||||
config.alphaMode = static_cast<filament::gltfio::AlphaMode>(materialConfig.alphaMode);
|
||||
config.hasBaseColorTexture = materialConfig.hasBaseColorTexture;
|
||||
config.hasClearCoat = materialConfig.hasClearCoat;
|
||||
config.hasClearCoatNormalTexture = materialConfig.hasClearCoatNormalTexture;
|
||||
config.hasClearCoatRoughnessTexture = materialConfig.hasClearCoatRoughnessTexture;
|
||||
config.hasEmissiveTexture = materialConfig.hasEmissiveTexture;
|
||||
config.hasIOR = materialConfig.hasIOR;
|
||||
config.hasMetallicRoughnessTexture = materialConfig.hasMetallicRoughnessTexture;
|
||||
config.hasNormalTexture = materialConfig.hasNormalTexture;
|
||||
config.hasOcclusionTexture = materialConfig.hasOcclusionTexture;
|
||||
config.hasSheen = materialConfig.hasSheen;
|
||||
config.hasSheenColorTexture = materialConfig.hasSheenColorTexture;
|
||||
config.hasSheenRoughnessTexture = materialConfig.hasSheenRoughnessTexture;
|
||||
config.hasTextureTransforms = materialConfig.hasTextureTransforms;
|
||||
config.hasTransmission = materialConfig.hasTransmission;
|
||||
config.hasTransmissionTexture = materialConfig.hasTransmissionTexture;
|
||||
config.hasVolume = materialConfig.hasVolume;
|
||||
config.hasVolumeThicknessTexture = materialConfig.hasVolumeThicknessTexture;
|
||||
config.baseColorUV = materialConfig.baseColorUV;
|
||||
config.hasVertexColors = materialConfig.hasVertexColors;
|
||||
auto materialInstance = ((SceneManager *)sceneManager)->createUbershaderMaterialInstance(config);
|
||||
return reinterpret_cast<TMaterialInstance*>(materialInstance);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(TSceneManager *sceneManager) {
|
||||
auto * instance = ((SceneManager*)sceneManager)->createUnlitMaterialInstance();
|
||||
return reinterpret_cast<TMaterialInstance*>(instance);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance) {
|
||||
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance*>(instance));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled) {
|
||||
reinterpret_cast<MaterialInstance*>(materialInstance)->setDepthWrite(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled) {
|
||||
reinterpret_cast<MaterialInstance*>(materialInstance)->setDepthCulling(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* propertyName, double x, double y) {
|
||||
filament::math::float2 data { static_cast<float>(x), static_cast<float>(y) };
|
||||
reinterpret_cast<MaterialInstance*>(materialInstance)->setParameter(propertyName, data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* tCamera, double4x4 projectionMatrix, double near, double far) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
camera->setCustomProjection(convert_double4x4_to_mat4(projectionMatrix), near, far);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* tCamera) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
return convert_mat4_to_double4x4(camera->getModelMatrix());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const tCamera) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
return convert_mat4_to_double4x4(camera->getViewMatrix());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* tCamera) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
return Entity::smuggle(camera->getEntity());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const tCamera) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
return camera->getFocalLength();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const tCamera) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
return camera->getNear();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const tCamera) {
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
return camera->getCullingFar();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId) {
|
||||
auto * engine = reinterpret_cast<Engine*>(tEngine);
|
||||
auto * camera = engine->getCameraComponent(utils::Entity::import(entityId));
|
||||
return reinterpret_cast<TCamera*>(camera);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_setTransform(TEngine* tEngine, EntityId entity, double4x4 transform) {
|
||||
auto * engine = reinterpret_cast<Engine*>(tEngine);
|
||||
auto& transformManager = engine->getTransformManager();
|
||||
|
||||
auto transformInstance = transformManager.getInstance(utils::Entity::import(entity));
|
||||
if(!transformInstance.isValid()) {
|
||||
Log("Transform instance not valid");
|
||||
// Set and log each field
|
||||
config.unlit = materialConfig.unlit;
|
||||
config.doubleSided = materialConfig.doubleSided;
|
||||
config.useSpecularGlossiness = materialConfig.useSpecularGlossiness;
|
||||
config.alphaMode = static_cast<filament::gltfio::AlphaMode>(materialConfig.alphaMode);
|
||||
config.hasBaseColorTexture = materialConfig.hasBaseColorTexture;
|
||||
config.hasClearCoat = materialConfig.hasClearCoat;
|
||||
config.hasClearCoatNormalTexture = materialConfig.hasClearCoatNormalTexture;
|
||||
config.hasClearCoatRoughnessTexture = materialConfig.hasClearCoatRoughnessTexture;
|
||||
config.hasEmissiveTexture = materialConfig.hasEmissiveTexture;
|
||||
config.hasIOR = materialConfig.hasIOR;
|
||||
config.hasMetallicRoughnessTexture = materialConfig.hasMetallicRoughnessTexture;
|
||||
config.hasNormalTexture = materialConfig.hasNormalTexture;
|
||||
config.hasOcclusionTexture = materialConfig.hasOcclusionTexture;
|
||||
config.hasSheen = materialConfig.hasSheen;
|
||||
config.hasSheenColorTexture = materialConfig.hasSheenColorTexture;
|
||||
config.hasSheenRoughnessTexture = materialConfig.hasSheenRoughnessTexture;
|
||||
config.hasTextureTransforms = materialConfig.hasTextureTransforms;
|
||||
config.hasTransmission = materialConfig.hasTransmission;
|
||||
config.hasTransmissionTexture = materialConfig.hasTransmissionTexture;
|
||||
config.hasVolume = materialConfig.hasVolume;
|
||||
config.hasVolumeThicknessTexture = materialConfig.hasVolumeThicknessTexture;
|
||||
config.baseColorUV = materialConfig.baseColorUV;
|
||||
config.hasVertexColors = materialConfig.hasVertexColors;
|
||||
auto materialInstance = ((SceneManager *)sceneManager)->createUbershaderMaterialInstance(config);
|
||||
return reinterpret_cast<TMaterialInstance *>(materialInstance);
|
||||
}
|
||||
transformManager.setTransform(transformInstance, convert_double4x4_to_mat4(transform));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_createCamera(TSceneManager* tSceneManager) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
return reinterpret_cast<TCamera*>(sceneManager->createCamera());
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(TSceneManager *sceneManager)
|
||||
{
|
||||
auto *instance = ((SceneManager *)sceneManager)->createUnlitMaterialInstance();
|
||||
return reinterpret_cast<TMaterialInstance *>(instance);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager* tSceneManager, TCamera* tCamera) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
sceneManager->destroyCamera(camera);
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance)
|
||||
{
|
||||
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance *>(instance));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_setCamera(TSceneManager* tSceneManager, TCamera* tCamera) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
auto * camera = reinterpret_cast<Camera*>(tCamera);
|
||||
sceneManager->setCamera(camera);
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance *materialInstance, bool enabled)
|
||||
{
|
||||
reinterpret_cast<MaterialInstance *>(materialInstance)->setDepthWrite(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *tSceneManager) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
return sceneManager->getCameraCount();
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *tSceneManager, size_t index) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
auto * camera = sceneManager->getCameraAt(index);
|
||||
return reinterpret_cast<TCamera*>(camera);
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance *materialInstance, bool enabled)
|
||||
{
|
||||
reinterpret_cast<MaterialInstance *>(materialInstance)->setDepthCulling(enabled);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y)
|
||||
{
|
||||
filament::math::float2 data{static_cast<float>(x), static_cast<float>(y)};
|
||||
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera *tCamera, double4x4 projectionMatrix, double near, double far)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
camera->setCustomProjection(convert_double4x4_to_mat4(projectionMatrix), near, far);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera *tCamera)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return convert_mat4_to_double4x4(camera->getModelMatrix());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const tCamera)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return convert_mat4_to_double4x4(camera->getViewMatrix());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera *tCamera)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return Entity::smuggle(camera->getEntity());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const tCamera)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return camera->getFocalLength();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const tCamera)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return camera->getNear();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const tCamera)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return camera->getCullingFar();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId)
|
||||
{
|
||||
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
||||
auto *camera = engine->getCameraComponent(utils::Entity::import(entityId));
|
||||
return reinterpret_cast<TCamera *>(camera);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_setTransform(TEngine *tEngine, EntityId entity, double4x4 transform)
|
||||
{
|
||||
auto *engine = reinterpret_cast<Engine *>(tEngine);
|
||||
auto &transformManager = engine->getTransformManager();
|
||||
|
||||
auto transformInstance = transformManager.getInstance(utils::Entity::import(entity));
|
||||
if (!transformInstance.isValid())
|
||||
{
|
||||
Log("Transform instance not valid");
|
||||
}
|
||||
transformManager.setTransform(transformInstance, convert_double4x4_to_mat4(transform));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_createCamera(TSceneManager *tSceneManager)
|
||||
{
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
return reinterpret_cast<TCamera *>(sceneManager->createCamera());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *tSceneManager, TCamera *tCamera)
|
||||
{
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
sceneManager->destroyCamera(camera);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *tSceneManager)
|
||||
{
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
return sceneManager->getCameraCount();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_getCameraAt(TSceneManager *tSceneManager, size_t index)
|
||||
{
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
auto *camera = sceneManager->getCameraAt(index);
|
||||
return reinterpret_cast<TCamera *>(camera);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getActiveCamera(TSceneManager *tSceneManager) {
|
||||
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||
auto * camera = sceneManager->getActiveCamera();
|
||||
return reinterpret_cast<TCamera*>(camera);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,9 +82,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void requestFrame(SwapChain* swapChain, void (*callback)())
|
||||
void requestFrame(TView* tView, TSwapChain* tSwapChain, void (*callback)())
|
||||
{
|
||||
this->target = swapChain;
|
||||
this->target = tSwapChain;
|
||||
this->view = tView;
|
||||
this->_requestFrameRenderCallback = callback;
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ public:
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
if (target)
|
||||
{
|
||||
doRender(target);
|
||||
doRender(view, target);
|
||||
this->_requestFrameRenderCallback();
|
||||
target = nullptr;
|
||||
|
||||
@@ -176,7 +177,7 @@ public:
|
||||
fut.wait();
|
||||
}
|
||||
|
||||
bool doRender(SwapChain *swapChain)
|
||||
bool doRender(TView* tView, TSwapChain *tSwapChain)
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (emscripten_is_webgl_context_lost(_context) == EM_TRUE)
|
||||
@@ -187,8 +188,7 @@ public:
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
TSwapChain *tSwapChain = reinterpret_cast<TSwapChain*>(swapChain);
|
||||
auto rendered = Viewer_render(_viewer, tSwapChain, 0, nullptr, nullptr, nullptr);
|
||||
auto rendered = Viewer_render(_viewer, tView, tSwapChain, 0, nullptr, nullptr, nullptr);
|
||||
if (_renderCallback)
|
||||
{
|
||||
_renderCallback(_renderCallbackOwner);
|
||||
@@ -218,7 +218,8 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
SwapChain* target;
|
||||
TSwapChain *target;
|
||||
TView *view;
|
||||
|
||||
private:
|
||||
void(*_requestFrameRenderCallback)() = nullptr;
|
||||
@@ -306,7 +307,7 @@ extern "C"
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, TSwapChain* tSwapChain, void(*onComplete)())
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, TView* view, TSwapChain* tSwapChain, void(*onComplete)())
|
||||
{
|
||||
if (!_rl)
|
||||
{
|
||||
@@ -314,7 +315,7 @@ extern "C"
|
||||
}
|
||||
else
|
||||
{
|
||||
_rl->requestFrame(reinterpret_cast<SwapChain*>(tSwapChain), onComplete);
|
||||
_rl->requestFrame(view, tSwapChain, onComplete);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,24 +328,24 @@ extern "C"
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TSwapChain *tSwapChain)
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView *tView, TSwapChain *tSwapChain)
|
||||
{
|
||||
std::packaged_task<void()> lambda([=]() mutable
|
||||
{ _rl->doRender(reinterpret_cast<SwapChain*>(tSwapChain)); });
|
||||
{ _rl->doRender(tView, tSwapChain); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TSwapChain *tSwapChain, uint8_t *pixelBuffer, void (*onComplete)())
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView *view, TSwapChain *tSwapChain, uint8_t *pixelBuffer, void (*onComplete)())
|
||||
{
|
||||
std::packaged_task<void()> lambda([=]() mutable
|
||||
{ Viewer_capture(viewer, tSwapChain, pixelBuffer, onComplete); });
|
||||
{ Viewer_capture(viewer, view, tSwapChain, pixelBuffer, onComplete); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TSwapChain *tSwapChain, TRenderTarget* tRenderTarget, uint8_t *pixelBuffer, void (*onComplete)())
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView *view, TSwapChain *tSwapChain, TRenderTarget* tRenderTarget, uint8_t *pixelBuffer, void (*onComplete)())
|
||||
{
|
||||
std::packaged_task<void()> lambda([=]() mutable
|
||||
{ Viewer_captureRenderTarget(viewer, tSwapChain, tRenderTarget, pixelBuffer, onComplete); });
|
||||
{ Viewer_captureRenderTarget(viewer, view, tSwapChain, tRenderTarget, pixelBuffer, onComplete); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
@@ -449,20 +450,7 @@ extern "C"
|
||||
{ set_background_image_position(viewer, x, y, clamp); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE void set_tone_mapping_render_thread(TViewer *viewer,
|
||||
int toneMapping)
|
||||
{
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]
|
||||
{ set_tone_mapping(viewer, toneMapping); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE void set_bloom_render_thread(TViewer *viewer, float strength)
|
||||
{
|
||||
std::packaged_task<void()> lambda([=]
|
||||
{ set_bloom(viewer, strength); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void load_skybox_render_thread(TViewer *viewer,
|
||||
const char *skyboxPath,
|
||||
void (*onComplete)())
|
||||
@@ -530,22 +518,6 @@ extern "C"
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_render_thread(TViewer *viewer, EntityId asset,
|
||||
const char *nodeName, void (*callback)(bool))
|
||||
{
|
||||
std::packaged_task<bool()> lambda(
|
||||
[=]
|
||||
{
|
||||
auto success = set_camera(viewer, asset, nodeName);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
MAIN_THREAD_EM_ASM({ moduleArg.dartFilamentResolveCallback($0, $1); }, callback, success);
|
||||
#else
|
||||
callback(success);
|
||||
#endif
|
||||
return success;
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void
|
||||
get_morph_target_name_render_thread(TSceneManager *sceneManager, EntityId assetEntity,
|
||||
@@ -637,15 +609,6 @@ extern "C"
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_post_processing_render_thread(TViewer *viewer,
|
||||
bool enabled)
|
||||
{
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]
|
||||
{ set_post_processing(viewer, enabled); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void
|
||||
get_name_for_entity_render_thread(TSceneManager *sceneManager, const EntityId entityId, void (*callback)(const char *))
|
||||
{
|
||||
|
||||
@@ -79,10 +79,11 @@ class TestHelper {
|
||||
outDir.createSync();
|
||||
}
|
||||
|
||||
Future capture(ThermionViewer viewer, String outputFilename) async {
|
||||
Future capture(ThermionViewer viewer, String outputFilename, { SwapChain? swapChain, RenderTarget? renderTarget}) async {
|
||||
await Future.delayed(Duration(milliseconds: 10));
|
||||
var outPath = p.join(outDir.path, "$outputFilename.bmp");
|
||||
var pixelBuffer = await viewer.capture(swapChain); //, renderTarget: renderTarget);
|
||||
var pixelBuffer =
|
||||
await viewer.capture(swapChain ?? this.swapChain, renderTarget: renderTarget);
|
||||
await savePixelBufferToBmp(
|
||||
pixelBuffer,
|
||||
viewer.viewportDimensions.$1.toInt(),
|
||||
@@ -91,17 +92,21 @@ class TestHelper {
|
||||
return pixelBuffer;
|
||||
}
|
||||
|
||||
Future<int> createTexture(int width, int height) async {
|
||||
final packageUri = findPackageRoot('thermion_dart');
|
||||
final lib = ThermionDartTexture1(DynamicLibrary.open(
|
||||
'${packageUri.toFilePath()}/native/lib/macos/swift/libthermion_swift.dylib'));
|
||||
final object = ThermionDartTexture.new1(lib);
|
||||
object.initWithWidth_height_(width, height);
|
||||
return object.metalTextureAddress;
|
||||
}
|
||||
|
||||
Future<ThermionViewer> createViewer(
|
||||
{img.Color? bg,
|
||||
Vector3? cameraPosition,
|
||||
viewportDimensions = (width: 500, height: 500)}) async {
|
||||
final packageUri = findPackageRoot('thermion_dart');
|
||||
|
||||
final lib = ThermionDartTexture1(DynamicLibrary.open(
|
||||
'${packageUri.toFilePath()}/native/lib/macos/swift/libthermion_swift.dylib'));
|
||||
final object = ThermionDartTexture.new1(lib);
|
||||
object.initWithWidth_height_(
|
||||
viewportDimensions.width, viewportDimensions.height);
|
||||
final texture =
|
||||
await createTexture(viewportDimensions.width, viewportDimensions.height);
|
||||
|
||||
final resourceLoader = calloc<ResourceLoaderWrapper>(1);
|
||||
var loadToOut = NativeCallable<
|
||||
@@ -118,11 +123,10 @@ class TestHelper {
|
||||
await viewer.initialized;
|
||||
swapChain = await viewer.createSwapChain(
|
||||
viewportDimensions.width, viewportDimensions.height);
|
||||
renderTarget = await viewer.createRenderTarget(
|
||||
viewportDimensions.width,
|
||||
viewportDimensions.height,
|
||||
object.metalTextureAddress);
|
||||
await viewer.setRenderTarget(renderTarget as FFIRenderTarget);
|
||||
renderTarget = await viewer.createRenderTarget(viewportDimensions.width,
|
||||
viewportDimensions.height, texture);
|
||||
|
||||
// await viewer.setRenderTarget(renderTarget as FFIRenderTarget);
|
||||
await viewer.updateViewportAndCameraProjection(
|
||||
viewportDimensions.width.toDouble(),
|
||||
viewportDimensions.height.toDouble());
|
||||
|
||||
21
thermion_dart/test/view_tests.dart
Normal file
21
thermion_dart/test/view_tests.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:test/test.dart';
|
||||
import 'helpers.dart';
|
||||
|
||||
void main() async {
|
||||
final testHelper = TestHelper("view");
|
||||
|
||||
group('view tests', () {
|
||||
test('create view', () async {
|
||||
var viewer = await testHelper.createViewer();
|
||||
final renderTarget = await viewer.createRenderTarget(
|
||||
200, 400, await testHelper.createTexture(200, 400));
|
||||
final view = await viewer.createView();
|
||||
|
||||
await view.updateViewport(200, 400);
|
||||
await view.setRenderTarget(renderTarget);
|
||||
await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0);
|
||||
await testHelper.capture(viewer, "create_view_with_render_target", renderTarget: renderTarget);
|
||||
await viewer.dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -240,7 +240,7 @@ class ThermionFlutterFFI extends ThermionFlutterPlatform {
|
||||
if (newTexture.hardwareTextureId != null) {
|
||||
// ignore: unused_local_variable
|
||||
var renderTarget = await _viewer!.createRenderTarget(
|
||||
width.toDouble(), height.toDouble(), newTexture.hardwareTextureId!);
|
||||
width, height, newTexture.hardwareTextureId!);
|
||||
}
|
||||
await _viewer!
|
||||
.updateViewportAndCameraProjection(width.toDouble(), height.toDouble());
|
||||
|
||||
Reference in New Issue
Block a user