feat: pass through fragment coordinates for picking
This commit is contained in:
@@ -29,7 +29,7 @@ class FFIGizmo extends BaseGizmo {
|
||||
}
|
||||
|
||||
void _onPickResult(DartEntityId entityId, int x, int y, Pointer<TView> view) {
|
||||
_callback?.call((entity: entityId, x: x, y: y));
|
||||
_callback?.call((entity: entityId, x: x, y: y, depth: 0, fragX: 0, fragY: 0, fragZ: 0));
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -150,8 +150,15 @@ external void Viewer_setViewRenderable(
|
||||
ffi.Int,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y,
|
||||
ffi.Pointer<TView> tView)>>)>(isLeaf: true)
|
||||
ffi.Void Function(
|
||||
EntityId entityId,
|
||||
ffi.Int x,
|
||||
ffi.Int y,
|
||||
ffi.Pointer<TView> tView,
|
||||
ffi.Float depth,
|
||||
ffi.Float fragX,
|
||||
ffi.Float fragY,
|
||||
ffi.Float fragZ)>>)>(isLeaf: true)
|
||||
external void Viewer_pick(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
ffi.Pointer<TView> tView,
|
||||
@@ -159,8 +166,15 @@ external void Viewer_pick(
|
||||
int y,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y,
|
||||
ffi.Pointer<TView> tView)>>
|
||||
ffi.Void Function(
|
||||
EntityId entityId,
|
||||
ffi.Int x,
|
||||
ffi.Int y,
|
||||
ffi.Pointer<TView> tView,
|
||||
ffi.Float depth,
|
||||
ffi.Float fragX,
|
||||
ffi.Float fragY,
|
||||
ffi.Float fragZ)>>
|
||||
callback,
|
||||
);
|
||||
|
||||
@@ -418,23 +432,6 @@ external ffi.Pointer<TMaterialInstance> create_material_instance(
|
||||
TMaterialKey materialConfig,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TMaterialInstance> Function(
|
||||
ffi.Pointer<TSceneManager>)>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterialInstance> SceneManager_createUnlitMaterialInstance(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
);
|
||||
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TMaterialInstance> Function(
|
||||
ffi.Pointer<TSceneManager>, ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterialInstance>)>>)>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterialInstance> SceneManager_createUnlitMaterialInstanceRenderThread(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterialInstance>)>>
|
||||
onComplete
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<TMaterialInstance>)>(isLeaf: true)
|
||||
@@ -618,6 +615,43 @@ external int get_bone(
|
||||
int boneIndex,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
EntityId Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Uint16>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<TMaterialInstance>,
|
||||
ffi.Bool)>(isLeaf: true)
|
||||
external int SceneManager_createGeometry(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<ffi.Float> vertices,
|
||||
int numVertices,
|
||||
ffi.Pointer<ffi.Float> normals,
|
||||
int numNormals,
|
||||
ffi.Pointer<ffi.Float> uvs,
|
||||
int numUvs,
|
||||
ffi.Pointer<ffi.Uint16> indices,
|
||||
int numIndices,
|
||||
int primitiveType,
|
||||
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||
bool keepData,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TMaterialInstance> Function(
|
||||
ffi.Pointer<TSceneManager>)>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterialInstance>
|
||||
SceneManager_createUnlitMaterialInstance(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId,
|
||||
ffi.Pointer<ffi.Double>)>(isLeaf: true)
|
||||
@@ -956,35 +990,6 @@ external void remove_animation_component(
|
||||
int entityId,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
EntityId Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Uint16>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<TMaterialInstance>,
|
||||
ffi.Bool)>(isLeaf: true)
|
||||
external int SceneManager_createGeometry(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<ffi.Float> vertices,
|
||||
int numVertices,
|
||||
ffi.Pointer<ffi.Float> normals,
|
||||
int numNormals,
|
||||
ffi.Pointer<ffi.Float> uvs,
|
||||
int numUvs,
|
||||
ffi.Pointer<ffi.Uint16> indices,
|
||||
int numIndices,
|
||||
int primitiveType,
|
||||
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||
bool keepData,
|
||||
);
|
||||
|
||||
@ffi.Native<EntityId Function(ffi.Pointer<TSceneManager>, EntityId)>(
|
||||
isLeaf: true)
|
||||
external int get_parent(
|
||||
@@ -1527,6 +1532,38 @@ external void remove_skybox_render_thread(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Uint16>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<TMaterialInstance>,
|
||||
ffi.Bool,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
||||
isLeaf: true)
|
||||
external void SceneManager_createGeometryRenderThread(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<ffi.Float> vertices,
|
||||
int numVertices,
|
||||
ffi.Pointer<ffi.Float> normals,
|
||||
int numNormals,
|
||||
ffi.Pointer<ffi.Float> uvs,
|
||||
int numUvs,
|
||||
ffi.Pointer<ffi.Uint16> indices,
|
||||
int numIndices,
|
||||
int primitiveType,
|
||||
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||
bool keepData,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
@@ -1551,6 +1588,20 @@ external void SceneManager_loadGlbFromBufferRenderThread(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TMaterialInstance>)>>)>(isLeaf: true)
|
||||
external void SceneManager_createUnlitMaterialInstanceRenderThread(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterialInstance>)>>
|
||||
callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
@@ -1751,38 +1802,6 @@ external void reset_to_rest_pose_render_thread(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TSceneManager>,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Int,
|
||||
ffi.Pointer<ffi.Uint16>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Pointer<TMaterialInstance>,
|
||||
ffi.Bool,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
||||
isLeaf: true)
|
||||
external void SceneManager_createGeometryRenderThread(
|
||||
ffi.Pointer<TSceneManager> sceneManager,
|
||||
ffi.Pointer<ffi.Float> vertices,
|
||||
int numVertices,
|
||||
ffi.Pointer<ffi.Float> normals,
|
||||
int numNormals,
|
||||
ffi.Pointer<ffi.Float> uvs,
|
||||
int numUvs,
|
||||
ffi.Pointer<ffi.Uint16> indices,
|
||||
int numIndices,
|
||||
int primitiveType,
|
||||
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||
bool keepData,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TViewer>,
|
||||
|
||||
@@ -84,7 +84,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
|
||||
_onPickResultCallable = NativeCallable<
|
||||
Void Function(EntityId entityId, Int x, Int y,
|
||||
Pointer<TView> view)>.listener(_onPickResult);
|
||||
Pointer<TView> view, Float depth, Float fragX, Float fragY, Float fragZ)>.listener(_onPickResult);
|
||||
|
||||
_initialize();
|
||||
}
|
||||
@@ -1509,23 +1509,23 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
}
|
||||
|
||||
void _onPickResult(
|
||||
ThermionEntity entityId, int x, int y, Pointer<TView> viewPtr) async {
|
||||
ThermionEntity entityId, int x, int y, Pointer<TView> viewPtr, double depth, double fragX, double fragY, double fragZ) async {
|
||||
final view = FFIView(viewPtr, _viewer!);
|
||||
final viewport = await view.getViewport();
|
||||
|
||||
_pickResultController
|
||||
.add((entity: entityId, x: x.ceil(), y: (viewport.height - y).ceil()));
|
||||
.add((entity: entityId, x: x.ceil(), y: (viewport.height - y).ceil(), depth: depth, fragX: fragX, fragY: viewport.height - fragY, fragZ: fragZ ));
|
||||
}
|
||||
|
||||
late NativeCallable<
|
||||
Void Function(EntityId entityId, Int x, Int y, Pointer<TView> view)>
|
||||
Void Function(EntityId entityId, Int x, Int y, Pointer<TView> view, Float depth, Float fragX, Float fragY, Float fragZ)>
|
||||
_onPickResultCallable;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
void pick(int x, int y) async {
|
||||
Future pick(int x, int y) async {
|
||||
final view = (await getViewAt(0)) as FFIView;
|
||||
var viewport = await view.getViewport();
|
||||
y = (viewport.height - y).ceil();
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
// "picking" means clicking/tapping on the viewport, and unprojecting the X/Y coordinate to determine whether any renderable entities were present at those coordinates.
|
||||
import '../../viewer.dart';
|
||||
|
||||
typedef FilamentPickResult = ({ThermionEntity entity, int x, int y});
|
||||
/// The result of a picking operation (see [ThermionViewer.pick] for more details).
|
||||
/// [x] and [y] refer to the original screen coordinates used to call [pick]; this should
|
||||
/// match the values of [fragX] and [fragY]. [fragZ] is the depth value in screen coordinates,
|
||||
/// [depth] is the value in the depth buffer (i.e. fragZ = 1.0 - depth).
|
||||
///
|
||||
typedef FilamentPickResult = ({
|
||||
ThermionEntity entity,
|
||||
int x,
|
||||
int y,
|
||||
double depth,
|
||||
double fragX,
|
||||
double fragY,
|
||||
double fragZ
|
||||
});
|
||||
typedef PickResult = FilamentPickResult;
|
||||
|
||||
@@ -695,7 +695,7 @@ abstract class ThermionViewer {
|
||||
/// This is asynchronous and will require 2-3 frames to complete - subscribe to the [pickResult] stream to receive the results of this method.
|
||||
/// [x] and [y] must be in local logical coordinates (i.e. where 0,0 is at top-left of the ThermionWidget).
|
||||
///
|
||||
void pick(int x, int y);
|
||||
Future pick(int x, int y);
|
||||
|
||||
///
|
||||
/// Retrieves the name assigned to the given ThermionEntity (usually corresponds to the glTF mesh name).
|
||||
|
||||
Reference in New Issue
Block a user