feat: camera and resizing improvements
This commit is contained in:
@@ -4,12 +4,14 @@ headers:
|
|||||||
- '../native/include/ThermionDartRenderThreadApi.h'
|
- '../native/include/ThermionDartRenderThreadApi.h'
|
||||||
- '../native/include/ThermionDartApi.h'
|
- '../native/include/ThermionDartApi.h'
|
||||||
- '../native/include/TView.h'
|
- '../native/include/TView.h'
|
||||||
|
- '../native/include/TCamera.h'
|
||||||
- '../native/include/TGizmo.h'
|
- '../native/include/TGizmo.h'
|
||||||
- '../native/include/ResourceBuffer.h'
|
- '../native/include/ResourceBuffer.h'
|
||||||
include-directives:
|
include-directives:
|
||||||
- '../native/include/ThermionDartRenderThreadApi.h'
|
- '../native/include/ThermionDartRenderThreadApi.h'
|
||||||
- '../native/include/ThermionDartApi.h'
|
- '../native/include/ThermionDartApi.h'
|
||||||
- '../native/include/TView.h'
|
- '../native/include/TView.h'
|
||||||
|
- '../native/include/TCamera.h'
|
||||||
- '../native/include/TGizmo.h'
|
- '../native/include/TGizmo.h'
|
||||||
- '../native/include/ResourceBuffer.h'
|
- '../native/include/ResourceBuffer.h'
|
||||||
- '../native/include/APIBoundaryTypes.h'
|
- '../native/include/APIBoundaryTypes.h'
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ import 'implementations/free_flight_camera_delegate.dart';
|
|||||||
class DelegateInputHandler implements InputHandler {
|
class DelegateInputHandler implements InputHandler {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
|
|
||||||
|
Stream<List<InputType>> get gestures => _gesturesController.stream;
|
||||||
|
|
||||||
|
final _gesturesController = StreamController<List<InputType>>.broadcast();
|
||||||
|
|
||||||
final _logger = Logger("DelegateInputHandler");
|
final _logger = Logger("DelegateInputHandler");
|
||||||
|
|
||||||
InputHandlerDelegate? transformDelegate;
|
InputHandlerDelegate? transformDelegate;
|
||||||
@@ -54,7 +58,7 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
|
|
||||||
factory DelegateInputHandler.fixedOrbit(ThermionViewer viewer,
|
factory DelegateInputHandler.fixedOrbit(ThermionViewer viewer,
|
||||||
{double minimumDistance = 10.0,
|
{double minimumDistance = 10.0,
|
||||||
double? Function(Vector3)? getDistanceToTarget,
|
Future<double?> Function(Vector3)? getDistanceToTarget,
|
||||||
ThermionEntity? entity,
|
ThermionEntity? entity,
|
||||||
PickDelegate? pickDelegate}) =>
|
PickDelegate? pickDelegate}) =>
|
||||||
DelegateInputHandler(
|
DelegateInputHandler(
|
||||||
@@ -105,39 +109,51 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
|
|
||||||
await transformDelegate?.queue(action, vector);
|
await transformDelegate?.queue(action, vector);
|
||||||
}
|
}
|
||||||
|
final keyTypes = <InputType>[];
|
||||||
for (final key in _pressedKeys) {
|
for (final key in _pressedKeys) {
|
||||||
InputAction? keyAction;
|
InputAction? keyAction;
|
||||||
|
InputType? keyType = null;
|
||||||
Vector3? vector;
|
Vector3? vector;
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case PhysicalKey.W:
|
case PhysicalKey.W:
|
||||||
keyAction = _actions[InputType.KEYDOWN_W];
|
keyType = InputType.KEYDOWN_W;
|
||||||
vector = Vector3(0, 0, -1);
|
vector = Vector3(0, 0, -1);
|
||||||
break;
|
break;
|
||||||
case PhysicalKey.A:
|
case PhysicalKey.A:
|
||||||
keyAction = _actions[InputType.KEYDOWN_A];
|
keyType = InputType.KEYDOWN_A;
|
||||||
vector = Vector3(-1, 0, 0);
|
vector = Vector3(-1, 0, 0);
|
||||||
break;
|
break;
|
||||||
case PhysicalKey.S:
|
case PhysicalKey.S:
|
||||||
keyAction = _actions[InputType.KEYDOWN_S];
|
keyType = InputType.KEYDOWN_S;
|
||||||
vector = Vector3(0, 0, 1);
|
vector = Vector3(0, 0, 1);
|
||||||
break;
|
break;
|
||||||
case PhysicalKey.D:
|
case PhysicalKey.D:
|
||||||
keyAction = _actions[InputType.KEYDOWN_D];
|
keyType = InputType.KEYDOWN_D;
|
||||||
vector = Vector3(1, 0, 0);
|
vector = Vector3(1, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (keyAction != null) {
|
|
||||||
var transform = _axes[keyAction];
|
if (keyType != null) {
|
||||||
if (transform != null) {
|
keyAction = _actions[keyType];
|
||||||
vector = transform * vector;
|
|
||||||
|
if (keyAction != null) {
|
||||||
|
var transform = _axes[keyAction];
|
||||||
|
if (transform != null) {
|
||||||
|
vector = transform * vector;
|
||||||
|
}
|
||||||
|
transformDelegate?.queue(keyAction, vector!);
|
||||||
|
keyTypes.add(keyType);
|
||||||
}
|
}
|
||||||
transformDelegate?.queue(keyAction, vector!);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await transformDelegate?.execute();
|
await transformDelegate?.execute();
|
||||||
|
var updates = _inputDeltas.keys.followedBy(keyTypes).toList();
|
||||||
|
if(updates.isNotEmpty) {
|
||||||
|
_gesturesController.add(updates);
|
||||||
|
}
|
||||||
|
|
||||||
_inputDeltas.clear();
|
_inputDeltas.clear();
|
||||||
_processing = false;
|
_processing = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import '../../../viewer/src/shared_types/camera.dart';
|
|||||||
import '../../../viewer/viewer.dart';
|
import '../../../viewer/viewer.dart';
|
||||||
import '../../input.dart';
|
import '../../input.dart';
|
||||||
import '../input_handler.dart';
|
import '../input_handler.dart';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
late Future<Camera> _camera;
|
late Future<Camera> _camera;
|
||||||
final double minimumDistance;
|
final double minimumDistance;
|
||||||
double? Function(Vector3)? getDistanceToTarget;
|
Future<double?> Function(Vector3)? getDistanceToTarget;
|
||||||
|
|
||||||
Vector2 _queuedRotationDelta = Vector2.zero();
|
Vector2 _queuedRotationDelta = Vector2.zero();
|
||||||
double _queuedZoomDelta = 0.0;
|
double _queuedZoomDelta = 0.0;
|
||||||
@@ -22,7 +23,14 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
this.getDistanceToTarget,
|
this.getDistanceToTarget,
|
||||||
this.minimumDistance = 10.0,
|
this.minimumDistance = 10.0,
|
||||||
}) {
|
}) {
|
||||||
_camera = viewer.getMainCamera();
|
_camera = viewer.getMainCamera().then((Camera cam) async {
|
||||||
|
var viewMatrix = makeViewMatrix(Vector3(0.0, 0, -minimumDistance),
|
||||||
|
Vector3.zero(), Vector3(0.0, 1.0, 0.0));
|
||||||
|
viewMatrix.invert();
|
||||||
|
|
||||||
|
await cam.setTransform(viewMatrix);
|
||||||
|
return cam;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@@ -50,12 +58,20 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _executing = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> execute() async {
|
Future<void> execute() async {
|
||||||
if (_queuedRotationDelta.length2 == 0.0 && _queuedZoomDelta == 0.0) {
|
if (_queuedRotationDelta.length2 == 0.0 && _queuedZoomDelta == 0.0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_executing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_executing = true;
|
||||||
|
|
||||||
final view = await viewer.getViewAt(0);
|
final view = await viewer.getViewAt(0);
|
||||||
final viewport = await view.getViewport();
|
final viewport = await view.getViewport();
|
||||||
|
|
||||||
@@ -66,15 +82,22 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
Vector3 currentPosition = modelMatrix.getTranslation();
|
Vector3 currentPosition = modelMatrix.getTranslation();
|
||||||
|
|
||||||
Vector3 forward = -currentPosition.normalized();
|
Vector3 forward = -currentPosition.normalized();
|
||||||
|
|
||||||
|
if (forward.length == 0) {
|
||||||
|
forward = Vector3(0, 0, -1);
|
||||||
|
currentPosition = Vector3(0, 0, minimumDistance);
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 right = _up.cross(forward).normalized();
|
Vector3 right = _up.cross(forward).normalized();
|
||||||
Vector3 up = forward.cross(right);
|
Vector3 up = forward.cross(right);
|
||||||
|
|
||||||
// Calculate intersection point and depth
|
// Calculate the point where the camera forward ray intersects with the
|
||||||
double radius = getDistanceToTarget?.call(currentPosition) ?? 1.0;
|
// surface of the target sphere
|
||||||
if (radius != 1.0) {
|
var distanceToTarget =
|
||||||
radius = currentPosition.length - radius;
|
(await getDistanceToTarget?.call(currentPosition)) ?? 0;
|
||||||
}
|
|
||||||
Vector3 intersection = (-forward).scaled(radius);
|
Vector3 intersection =
|
||||||
|
(-forward).scaled(currentPosition.length - distanceToTarget);
|
||||||
|
|
||||||
final intersectionInViewSpace = viewMatrix *
|
final intersectionInViewSpace = viewMatrix *
|
||||||
Vector4(intersection.x, intersection.y, intersection.z, 1.0);
|
Vector4(intersection.x, intersection.y, intersection.z, 1.0);
|
||||||
@@ -98,17 +121,45 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
var worldSpace3 = worldSpace.xyz.normalized() * currentPosition.length;
|
var worldSpace3 = worldSpace.xyz.normalized() * currentPosition.length;
|
||||||
currentPosition = worldSpace3;
|
currentPosition = worldSpace3;
|
||||||
|
|
||||||
// Apply zoom
|
// Zoom
|
||||||
if (_queuedZoomDelta != 0.0) {
|
if (_queuedZoomDelta != 0.0) {
|
||||||
Vector3 toSurface = currentPosition - intersection;
|
var distToIntersection =
|
||||||
currentPosition =
|
(currentPosition - intersection).length - minimumDistance;
|
||||||
currentPosition + toSurface.scaled(_queuedZoomDelta * 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure minimum distance
|
// if we somehow overshot the minimum distance, reset the camera to the minimum distance
|
||||||
if (currentPosition.length < radius + minimumDistance) {
|
if (distToIntersection < 0) {
|
||||||
currentPosition =
|
currentPosition +=
|
||||||
(currentPosition.normalized() * (radius + minimumDistance));
|
(intersection.normalized().scaled(-distToIntersection * 10));
|
||||||
|
} else {
|
||||||
|
bool zoomingOut = _queuedZoomDelta > 0;
|
||||||
|
late Vector3 offset;
|
||||||
|
|
||||||
|
// when zooming, we don't always use fractions of the distance from
|
||||||
|
// the camera to the target (this is due to float precision issues at
|
||||||
|
// large distances, and also it doesn't work well for UI).
|
||||||
|
|
||||||
|
// if we're zooming out and the distance is less than 10m, we zoom out by 1 unit
|
||||||
|
if (zoomingOut) {
|
||||||
|
if (distToIntersection < 10) {
|
||||||
|
offset = intersection.normalized();
|
||||||
|
} else {
|
||||||
|
offset = intersection.normalized().scaled(distToIntersection / 10);
|
||||||
|
}
|
||||||
|
// if we're zooming in and the distance is less than 5m, zoom in by 1/2 the distance,
|
||||||
|
// otherwise 1/10 of the distance each time
|
||||||
|
} else {
|
||||||
|
if (distToIntersection < 5) {
|
||||||
|
offset = intersection.normalized().scaled(-distToIntersection / 2);
|
||||||
|
} else {
|
||||||
|
offset = intersection.normalized().scaled(-distToIntersection / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset.length > distToIntersection) {
|
||||||
|
offset = Vector3.zero();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentPosition += offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate view matrix
|
// Calculate view matrix
|
||||||
@@ -126,5 +177,7 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
|||||||
// Reset queued deltas
|
// Reset queued deltas
|
||||||
_queuedRotationDelta = Vector2.zero();
|
_queuedRotationDelta = Vector2.zero();
|
||||||
_queuedZoomDelta = 0.0;
|
_queuedZoomDelta = 0.0;
|
||||||
|
|
||||||
|
_executing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ enum PhysicalKey { W, A, S, D }
|
|||||||
enum InputAction { TRANSLATE, ROTATE, PICK, NONE }
|
enum InputAction { TRANSLATE, ROTATE, PICK, NONE }
|
||||||
|
|
||||||
abstract class InputHandler {
|
abstract class InputHandler {
|
||||||
|
Stream<List<InputType>> get gestures;
|
||||||
|
|
||||||
Future<void> onPointerHover(Vector2 localPosition, Vector2 delta);
|
Future<void> onPointerHover(Vector2 localPosition, Vector2 delta);
|
||||||
Future<void> onPointerScroll(Vector2 localPosition, double scrollDelta);
|
Future<void> onPointerScroll(Vector2 localPosition, double scrollDelta);
|
||||||
Future<void> onPointerDown(Vector2 localPosition, bool isMiddle);
|
Future<void> onPointerDown(Vector2 localPosition, bool isMiddle);
|
||||||
Future<void> onPointerMove(Vector2 localPosition, Vector2 delta, bool isMiddle);
|
Future<void> onPointerMove(
|
||||||
|
Vector2 localPosition, Vector2 delta, bool isMiddle);
|
||||||
Future<void> onPointerUp(bool isMiddle);
|
Future<void> onPointerUp(bool isMiddle);
|
||||||
Future<void> onScaleStart();
|
Future<void> onScaleStart();
|
||||||
Future<void> onScaleUpdate();
|
Future<void> onScaleUpdate();
|
||||||
|
|||||||
@@ -4,32 +4,32 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
|
|
||||||
import '../../../../utils/matrix.dart';
|
import '../../../../utils/matrix.dart';
|
||||||
import '../../thermion_viewer_base.dart';
|
import '../../thermion_viewer_base.dart';
|
||||||
import 'thermion_dart.g.dart';
|
import 'thermion_dart.g.dart' as g;
|
||||||
|
|
||||||
class FFICamera extends Camera {
|
class FFICamera extends Camera {
|
||||||
final Pointer<TCamera> camera;
|
final Pointer<g.TCamera> camera;
|
||||||
final Pointer<TEngine> engine;
|
final Pointer<g.TEngine> engine;
|
||||||
late ThermionEntity _entity;
|
late ThermionEntity _entity;
|
||||||
|
|
||||||
FFICamera(this.camera, this.engine) {
|
FFICamera(this.camera, this.engine) {
|
||||||
_entity = Camera_getEntity(camera);
|
_entity = g.Camera_getEntity(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setProjectionMatrixWithCulling(
|
Future setProjectionMatrixWithCulling(
|
||||||
Matrix4 projectionMatrix, double near, double far) async {
|
Matrix4 projectionMatrix, double near, double far) async {
|
||||||
Camera_setCustomProjectionWithCulling(
|
g.Camera_setCustomProjectionWithCulling(
|
||||||
camera, matrix4ToDouble4x4(projectionMatrix), near, far);
|
camera, matrix4ToDouble4x4(projectionMatrix), near, far);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Matrix4> getModelMatrix() async {
|
Future<Matrix4> getModelMatrix() async {
|
||||||
return double4x4ToMatrix4(Camera_getModelMatrix(camera));
|
return double4x4ToMatrix4(g.Camera_getModelMatrix(camera));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setTransform(Matrix4 transform) async {
|
Future setTransform(Matrix4 transform) async {
|
||||||
var entity = Camera_getEntity(camera);
|
var entity = g.Camera_getEntity(camera);
|
||||||
Engine_setTransform(engine, entity, matrix4ToDouble4x4(transform));
|
g.Engine_setTransform(engine, entity, matrix4ToDouble4x4(transform));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -38,7 +38,7 @@ class FFICamera extends Camera {
|
|||||||
double far = kFar,
|
double far = kFar,
|
||||||
double aspect = 1.0,
|
double aspect = 1.0,
|
||||||
double focalLength = kFocalLength}) async {
|
double focalLength = kFocalLength}) async {
|
||||||
Camera_setLensProjection(camera, near, far, aspect, focalLength);
|
g.Camera_setLensProjection(camera, near, far, aspect, focalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -48,7 +48,7 @@ class FFICamera extends Camera {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setModelMatrix(Matrix4 matrix) async {
|
Future setModelMatrix(Matrix4 matrix) async {
|
||||||
Camera_setModelMatrix(camera, matrix4ToDouble4x4(matrix));
|
g.Camera_setModelMatrix(camera, matrix4ToDouble4x4(matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -63,21 +63,29 @@ class FFICamera extends Camera {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<double> getCullingFar() async {
|
Future<double> getCullingFar() async {
|
||||||
return Camera_getCullingFar(camera);
|
return g.Camera_getCullingFar(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<double> getNear() async {
|
Future<double> getNear() async {
|
||||||
return Camera_getNear(camera);
|
return g.Camera_getNear(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<double> getFocalLength() async {
|
Future<double> getFocalLength() async {
|
||||||
return Camera_getFocalLength(camera);
|
return g.Camera_getFocalLength(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Matrix4> getViewMatrix() async {
|
Future<Matrix4> getViewMatrix() async {
|
||||||
return double4x4ToMatrix4(Camera_getViewMatrix(camera));
|
return double4x4ToMatrix4(g.Camera_getViewMatrix(camera));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setProjection(Projection projection, double left, double right,
|
||||||
|
double bottom, double top, double near, double far) async {
|
||||||
|
var pType = g.Projection.values[projection.index];
|
||||||
|
g.Camera_setProjection(camera, pType, left,
|
||||||
|
right, bottom, top, near, far);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
|
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/shared_types/camera.dart';
|
|
||||||
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
|
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
|
||||||
|
import 'ffi_camera.dart';
|
||||||
import '../../shared_types/view.dart';
|
|
||||||
import '../thermion_viewer_ffi.dart';
|
|
||||||
import 'thermion_viewer_ffi.dart';
|
import 'thermion_viewer_ffi.dart';
|
||||||
|
|
||||||
class FFIView extends View {
|
class FFIView extends View {
|
||||||
@@ -54,4 +50,20 @@ class FFIView extends View {
|
|||||||
Future setRenderable(bool renderable, FFISwapChain swapChain) async {
|
Future setRenderable(bool renderable, FFISwapChain swapChain) async {
|
||||||
Viewer_setViewRenderable(viewer, swapChain.swapChain, view, renderable);
|
Viewer_setViewRenderable(viewer, swapChain.swapChain, view, renderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setFrustumCullingEnabled(bool enabled) async {
|
||||||
|
View_setFrustumCullingEnabled(view, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setBloom(double strength) async {
|
||||||
|
View_setBloom(view, strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setToneMapper(ToneMapper mapper) async {
|
||||||
|
final engine = await Viewer_getEngine(viewer);
|
||||||
|
View_setToneMappingRenderThread(view, engine, mapper.index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,16 @@ external ffi.Pointer<ffi.Void> make_resource_loader(
|
|||||||
ffi.Pointer<ffi.Void> owner,
|
ffi.Pointer<ffi.Void> owner,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Pointer<TViewer> Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>,
|
||||||
|
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TViewer> Viewer_create(
|
||||||
|
ffi.Pointer<ffi.Void> context,
|
||||||
|
ffi.Pointer<ffi.Void> loader,
|
||||||
|
ffi.Pointer<ffi.Void> platform,
|
||||||
|
ffi.Pointer<ffi.Char> uberArchivePath,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||||
external void destroy_filament_viewer(
|
external void destroy_filament_viewer(
|
||||||
ffi.Pointer<TViewer> viewer,
|
ffi.Pointer<TViewer> viewer,
|
||||||
@@ -197,12 +207,6 @@ external void set_background_color(
|
|||||||
double a,
|
double a,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float)>(isLeaf: true)
|
|
||||||
external void set_bloom(
|
|
||||||
ffi.Pointer<TViewer> viewer,
|
|
||||||
double strength,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<ffi.Char>)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<ffi.Char>)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external void load_skybox(
|
external void load_skybox(
|
||||||
@@ -329,18 +333,6 @@ external int load_glb(
|
|||||||
bool keepData,
|
bool keepData,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
EntityId Function(ffi.Pointer<TSceneManager>, ffi.Pointer<ffi.Void>,
|
|
||||||
ffi.Size, ffi.Bool, ffi.Int, ffi.Int)>(isLeaf: true)
|
|
||||||
external int load_glb_from_buffer(
|
|
||||||
ffi.Pointer<TSceneManager> sceneManager,
|
|
||||||
ffi.Pointer<ffi.Void> data,
|
|
||||||
int length,
|
|
||||||
bool keepData,
|
|
||||||
int priority,
|
|
||||||
int layer,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
EntityId Function(ffi.Pointer<TSceneManager>, ffi.Pointer<ffi.Char>,
|
EntityId Function(ffi.Pointer<TSceneManager>, ffi.Pointer<ffi.Char>,
|
||||||
ffi.Pointer<ffi.Char>, ffi.Bool)>(isLeaf: true)
|
ffi.Pointer<ffi.Char>, ffi.Bool)>(isLeaf: true)
|
||||||
@@ -379,12 +371,6 @@ external int get_main_camera(
|
|||||||
ffi.Pointer<TViewer> viewer,
|
ffi.Pointer<TViewer> viewer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Bool)>(isLeaf: true)
|
|
||||||
external void set_view_frustum_culling(
|
|
||||||
ffi.Pointer<TViewer> viewer,
|
|
||||||
bool enabled,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float)>(isLeaf: true)
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float)>(isLeaf: true)
|
||||||
external void set_frame_interval(
|
external void set_frame_interval(
|
||||||
ffi.Pointer<TViewer> viewer,
|
ffi.Pointer<TViewer> viewer,
|
||||||
@@ -671,6 +657,18 @@ external ffi.Pointer<TScene> SceneManager_getScene(
|
|||||||
ffi.Pointer<TSceneManager> tSceneManager,
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
EntityId Function(ffi.Pointer<TSceneManager>, ffi.Pointer<ffi.Uint8>,
|
||||||
|
ffi.Size, ffi.Bool, ffi.Int, ffi.Int)>(isLeaf: true)
|
||||||
|
external int SceneManager_loadGlbFromBuffer(
|
||||||
|
ffi.Pointer<TSceneManager> sceneManager,
|
||||||
|
ffi.Pointer<ffi.Uint8> arg1,
|
||||||
|
int length,
|
||||||
|
bool keepData,
|
||||||
|
int priority,
|
||||||
|
int layer,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId)>(
|
@ffi.Native<ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external bool update_bone_matrices(
|
external bool update_bone_matrices(
|
||||||
@@ -792,161 +790,6 @@ external void set_scale(
|
|||||||
double scale,
|
double scale,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Void Function(
|
|
||||||
ffi.Pointer<TCamera>, ffi.Float, ffi.Float, ffi.Float)>(isLeaf: true)
|
|
||||||
external void set_camera_exposure(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double aperture,
|
|
||||||
double shutterSpeed,
|
|
||||||
double sensitivity,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, double4x4)>(isLeaf: true)
|
|
||||||
external void set_camera_model_matrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double4x4 matrix,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TViewer>, EntityId)>(
|
|
||||||
isLeaf: true)
|
|
||||||
external ffi.Pointer<TCamera> get_camera(
|
|
||||||
ffi.Pointer<TViewer> viewer,
|
|
||||||
int entity,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double4x4 get_camera_model_matrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double4x4 get_camera_view_matrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double4x4 get_camera_projection_matrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double4x4 get_camera_culling_projection_matrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<ffi.Double> Function(ffi.Pointer<TCamera>)>(
|
|
||||||
isLeaf: true)
|
|
||||||
external ffi.Pointer<ffi.Double> get_camera_frustum(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Void Function(
|
|
||||||
ffi.Pointer<TCamera>, double4x4, ffi.Double, ffi.Double)>(isLeaf: true)
|
|
||||||
external void set_camera_projection_matrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double4x4 matrix,
|
|
||||||
double near,
|
|
||||||
double far,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Void Function(ffi.Pointer<TCamera>, ffi.Double, ffi.Double, ffi.Double,
|
|
||||||
ffi.Double, ffi.Bool)>(isLeaf: true)
|
|
||||||
external void set_camera_projection_from_fov(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double fovInDegrees,
|
|
||||||
double aspect,
|
|
||||||
double near,
|
|
||||||
double far,
|
|
||||||
bool horizontal,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double get_camera_focal_length(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double Camera_getFocalLength(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double Camera_getNear(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double Camera_getCullingFar(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double4x4 Camera_getViewMatrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double4x4 Camera_getModelMatrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double get_camera_near(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external double get_camera_culling_far(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Float Function(ffi.Pointer<TCamera>, ffi.Bool)>(isLeaf: true)
|
|
||||||
external double get_camera_fov(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
bool horizontal,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, ffi.Float)>(isLeaf: true)
|
|
||||||
external void set_camera_focus_distance(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double focusDistance,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Void Function(
|
|
||||||
ffi.Pointer<TCamera>, double4x4, ffi.Double, ffi.Double)>(isLeaf: true)
|
|
||||||
external void Camera_setCustomProjectionWithCulling(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double4x4 projectionMatrix,
|
|
||||||
double near,
|
|
||||||
double far,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, double4x4)>(isLeaf: true)
|
|
||||||
external void Camera_setModelMatrix(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double4x4 modelMatrix,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Void Function(ffi.Pointer<TCamera>, ffi.Double, ffi.Double, ffi.Double,
|
|
||||||
ffi.Double)>(isLeaf: true)
|
|
||||||
external void Camera_setLensProjection(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
double near,
|
|
||||||
double far,
|
|
||||||
double aspect,
|
|
||||||
double focalLength,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<EntityId Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
|
||||||
external int Camera_getEntity(
|
|
||||||
ffi.Pointer<TCamera> camera,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<TEntityManager> Function(ffi.Pointer<TEngine>)>(
|
@ffi.Native<ffi.Pointer<TEntityManager> Function(ffi.Pointer<TEngine>)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external ffi.Pointer<TEntityManager> Engine_getEntityManager(
|
external ffi.Pointer<TEntityManager> Engine_getEntityManager(
|
||||||
@@ -1350,6 +1193,119 @@ external void MaterialInstance_setParameterFloat2(
|
|||||||
double y,
|
double y,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
|
||||||
|
external TViewport View_getViewport(
|
||||||
|
ffi.Pointer<TView> view,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external void View_updateViewport(
|
||||||
|
ffi.Pointer<TView> view,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TRenderTarget>)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external void View_setRenderTarget(
|
||||||
|
ffi.Pointer<TView> view,
|
||||||
|
ffi.Pointer<TRenderTarget> renderTarget,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
|
||||||
|
external void View_setFrustumCullingEnabled(
|
||||||
|
ffi.Pointer<TView> view,
|
||||||
|
bool enabled,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.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.UnsignedInt)>(symbol: "View_setToneMapping", isLeaf: true)
|
||||||
|
external void _View_setToneMapping(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
int toneMapping,
|
||||||
|
);
|
||||||
|
|
||||||
|
void View_setToneMapping(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
ToneMapping toneMapping,
|
||||||
|
) =>
|
||||||
|
_View_setToneMapping(
|
||||||
|
tView,
|
||||||
|
tEngine,
|
||||||
|
toneMapping.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TView>, ffi.Bool, ffi.Bool, ffi.Bool)>(isLeaf: true)
|
||||||
|
external void View_setAntiAliasing(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
bool msaa,
|
||||||
|
bool fxaa,
|
||||||
|
bool taa,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Int, ffi.Bool)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external void View_setLayerEnabled(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
int layer,
|
||||||
|
bool visible,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TCamera>)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external void View_setCamera(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TCamera> tCamera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TView>)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TScene> View_getScene(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TView>)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TCamera> View_getCamera(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>,
|
ffi.Pointer<ffi.Void>,
|
||||||
@@ -1468,6 +1424,21 @@ external void Viewer_requestFrameRenderThread(
|
|||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TView>, ffi.Pointer<TEngine>, ffi.Int)>(isLeaf: true)
|
||||||
|
external void View_setToneMappingRenderThread(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
int arg2,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Double)>(isLeaf: true)
|
||||||
|
external void View_setBloomRenderThread(
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
double bloom,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||||
external void destroy_filament_viewer_render_thread(
|
external void destroy_filament_viewer_render_thread(
|
||||||
ffi.Pointer<TViewer> viewer,
|
ffi.Pointer<TViewer> viewer,
|
||||||
@@ -1530,18 +1501,6 @@ external void set_background_image_position_render_thread(
|
|||||||
bool clamp,
|
bool clamp,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Int)>(isLeaf: true)
|
|
||||||
external void set_tone_mapping_render_thread(
|
|
||||||
ffi.Pointer<TViewer> viewer,
|
|
||||||
int toneMapping,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>, ffi.Float)>(isLeaf: true)
|
|
||||||
external void set_bloom_render_thread(
|
|
||||||
ffi.Pointer<TViewer> viewer,
|
|
||||||
double strength,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<ffi.Char>,
|
ffi.Void Function(ffi.Pointer<TViewer>, ffi.Pointer<ffi.Char>,
|
||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||||
@@ -1556,6 +1515,28 @@ external void remove_skybox_render_thread(
|
|||||||
ffi.Pointer<TViewer> viewer,
|
ffi.Pointer<TViewer> viewer,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TSceneManager>,
|
||||||
|
ffi.Pointer<ffi.Uint8>,
|
||||||
|
ffi.Size,
|
||||||
|
ffi.Int,
|
||||||
|
ffi.Bool,
|
||||||
|
ffi.Int,
|
||||||
|
ffi.Int,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external void SceneManager_loadGlbFromBufferRenderThread(
|
||||||
|
ffi.Pointer<TSceneManager> sceneManager,
|
||||||
|
ffi.Pointer<ffi.Uint8> data,
|
||||||
|
int length,
|
||||||
|
int numInstances,
|
||||||
|
bool keepData,
|
||||||
|
int priority,
|
||||||
|
int layer,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
@@ -1572,28 +1553,6 @@ external void load_glb_render_thread(
|
|||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Void Function(
|
|
||||||
ffi.Pointer<TSceneManager>,
|
|
||||||
ffi.Pointer<ffi.Uint8>,
|
|
||||||
ffi.Size,
|
|
||||||
ffi.Int,
|
|
||||||
ffi.Bool,
|
|
||||||
ffi.Int,
|
|
||||||
ffi.Int,
|
|
||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
|
||||||
isLeaf: true)
|
|
||||||
external void load_glb_from_buffer_render_thread(
|
|
||||||
ffi.Pointer<TSceneManager> sceneManager,
|
|
||||||
ffi.Pointer<ffi.Uint8> data,
|
|
||||||
int length,
|
|
||||||
int numInstances,
|
|
||||||
bool keepData,
|
|
||||||
int priority,
|
|
||||||
int layer,
|
|
||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>> callback,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
@@ -1833,118 +1792,202 @@ external void unproject_texture_render_thread(
|
|||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
|
|
||||||
external TViewport View_getViewport(
|
|
||||||
ffi.Pointer<TView> view,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
|
|
||||||
isLeaf: true)
|
|
||||||
external void View_updateViewport(
|
|
||||||
ffi.Pointer<TView> view,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TRenderTarget>)>(
|
|
||||||
isLeaf: true)
|
|
||||||
external void View_setRenderTarget(
|
|
||||||
ffi.Pointer<TView> view,
|
|
||||||
ffi.Pointer<TRenderTarget> renderTarget,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Bool)>(isLeaf: true)
|
|
||||||
external void View_setFrustumCullingEnabled(
|
|
||||||
ffi.Pointer<TView> view,
|
|
||||||
bool enabled,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.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.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TEngine>,
|
ffi.Void Function(
|
||||||
ffi.UnsignedInt)>(symbol: "View_setToneMapping", isLeaf: true)
|
ffi.Pointer<TCamera>, ffi.Float, ffi.Float, ffi.Float)>(isLeaf: true)
|
||||||
external void _View_setToneMapping(
|
external void set_camera_exposure(
|
||||||
ffi.Pointer<TView> tView,
|
ffi.Pointer<TCamera> camera,
|
||||||
ffi.Pointer<TEngine> tEngine,
|
double aperture,
|
||||||
int toneMapping,
|
double shutterSpeed,
|
||||||
|
double sensitivity,
|
||||||
);
|
);
|
||||||
|
|
||||||
void View_setToneMapping(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, double4x4)>(isLeaf: true)
|
||||||
ffi.Pointer<TView> tView,
|
external void set_camera_model_matrix(
|
||||||
ffi.Pointer<TEngine> tEngine,
|
ffi.Pointer<TCamera> camera,
|
||||||
ToneMapping toneMapping,
|
double4x4 matrix,
|
||||||
) =>
|
);
|
||||||
_View_setToneMapping(
|
|
||||||
tView,
|
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TViewer>, EntityId)>(
|
||||||
tEngine,
|
isLeaf: true)
|
||||||
toneMapping.value,
|
external ffi.Pointer<TCamera> get_camera(
|
||||||
);
|
ffi.Pointer<TViewer> viewer,
|
||||||
|
int entity,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double4x4 get_camera_model_matrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double4x4 get_camera_view_matrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double4x4 get_camera_projection_matrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double4x4 get_camera_culling_projection_matrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Pointer<ffi.Double> Function(ffi.Pointer<TCamera>)>(
|
||||||
|
isLeaf: true)
|
||||||
|
external ffi.Pointer<ffi.Double> get_camera_frustum(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<TView>, ffi.Bool, ffi.Bool, ffi.Bool)>(isLeaf: true)
|
ffi.Pointer<TCamera>, double4x4, ffi.Double, ffi.Double)>(isLeaf: true)
|
||||||
external void View_setAntiAliasing(
|
external void set_camera_projection_matrix(
|
||||||
ffi.Pointer<TView> tView,
|
ffi.Pointer<TCamera> camera,
|
||||||
bool msaa,
|
double4x4 matrix,
|
||||||
bool fxaa,
|
double near,
|
||||||
bool taa,
|
double far,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Int, ffi.Bool)>(
|
@ffi.Native<
|
||||||
isLeaf: true)
|
ffi.Void Function(ffi.Pointer<TCamera>, ffi.Double, ffi.Double, ffi.Double,
|
||||||
external void View_setLayerEnabled(
|
ffi.Double, ffi.Bool)>(isLeaf: true)
|
||||||
ffi.Pointer<TView> tView,
|
external void set_camera_projection_from_fov(
|
||||||
int layer,
|
ffi.Pointer<TCamera> camera,
|
||||||
bool visible,
|
double fovInDegrees,
|
||||||
|
double aspect,
|
||||||
|
double near,
|
||||||
|
double far,
|
||||||
|
bool horizontal,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TCamera>)>(
|
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
isLeaf: true)
|
external double get_camera_focal_length(
|
||||||
external void View_setCamera(
|
ffi.Pointer<TCamera> camera,
|
||||||
ffi.Pointer<TView> tView,
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double Camera_getFocalLength(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double Camera_getNear(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double Camera_getCullingFar(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double4x4 Camera_getViewMatrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double4x4 Camera_getModelMatrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double get_camera_near(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external double get_camera_culling_far(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Float Function(ffi.Pointer<TCamera>, ffi.Bool)>(isLeaf: true)
|
||||||
|
external double get_camera_fov(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
bool horizontal,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, ffi.Float)>(isLeaf: true)
|
||||||
|
external void set_camera_focus_distance(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
double focusDistance,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TCamera>, double4x4, ffi.Double, ffi.Double)>(isLeaf: true)
|
||||||
|
external void Camera_setCustomProjectionWithCulling(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
double4x4 projectionMatrix,
|
||||||
|
double near,
|
||||||
|
double far,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, double4x4)>(isLeaf: true)
|
||||||
|
external void Camera_setModelMatrix(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
double4x4 modelMatrix,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TCamera>, ffi.Double, ffi.Double, ffi.Double,
|
||||||
|
ffi.Double)>(isLeaf: true)
|
||||||
|
external void Camera_setLensProjection(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
double near,
|
||||||
|
double far,
|
||||||
|
double aspect,
|
||||||
|
double focalLength,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<EntityId Function(ffi.Pointer<TCamera>)>(isLeaf: true)
|
||||||
|
external int Camera_getEntity(
|
||||||
|
ffi.Pointer<TCamera> camera,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TCamera>,
|
||||||
|
ffi.UnsignedInt,
|
||||||
|
ffi.Double,
|
||||||
|
ffi.Double,
|
||||||
|
ffi.Double,
|
||||||
|
ffi.Double,
|
||||||
|
ffi.Double,
|
||||||
|
ffi.Double)>(symbol: "Camera_setProjection", isLeaf: true)
|
||||||
|
external void _Camera_setProjection(
|
||||||
ffi.Pointer<TCamera> tCamera,
|
ffi.Pointer<TCamera> tCamera,
|
||||||
|
int projection,
|
||||||
|
double left,
|
||||||
|
double right,
|
||||||
|
double bottom,
|
||||||
|
double top,
|
||||||
|
double near,
|
||||||
|
double far,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TView>)>(isLeaf: true)
|
void Camera_setProjection(
|
||||||
external ffi.Pointer<TScene> View_getScene(
|
ffi.Pointer<TCamera> tCamera,
|
||||||
ffi.Pointer<TView> tView,
|
Projection projection,
|
||||||
);
|
double left,
|
||||||
|
double right,
|
||||||
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TView>)>(isLeaf: true)
|
double bottom,
|
||||||
external ffi.Pointer<TCamera> View_getCamera(
|
double top,
|
||||||
ffi.Pointer<TView> tView,
|
double near,
|
||||||
);
|
double far,
|
||||||
|
) =>
|
||||||
|
_Camera_setProjection(
|
||||||
|
tCamera,
|
||||||
|
projection.value,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
bottom,
|
||||||
|
top,
|
||||||
|
near,
|
||||||
|
far,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<TGizmo> Function(ffi.Pointer<TEngine>, ffi.Pointer<TView>,
|
ffi.Pointer<TGizmo> Function(ffi.Pointer<TEngine>, ffi.Pointer<TView>,
|
||||||
@@ -2218,12 +2261,6 @@ typedef DartLoadFilamentResourceIntoOutPointerFunction = void Function(
|
|||||||
/// - setting up a render loop
|
/// - setting up a render loop
|
||||||
typedef EntityId = ffi.Int32;
|
typedef EntityId = ffi.Int32;
|
||||||
typedef DartEntityId = int;
|
typedef DartEntityId = int;
|
||||||
typedef FilamentRenderCallback
|
|
||||||
= ffi.Pointer<ffi.NativeFunction<FilamentRenderCallbackFunction>>;
|
|
||||||
typedef FilamentRenderCallbackFunction = ffi.Void Function(
|
|
||||||
ffi.Pointer<ffi.Void> owner);
|
|
||||||
typedef DartFilamentRenderCallbackFunction = void Function(
|
|
||||||
ffi.Pointer<ffi.Void> owner);
|
|
||||||
|
|
||||||
final class TViewport extends ffi.Struct {
|
final class TViewport extends ffi.Struct {
|
||||||
@ffi.Int32()
|
@ffi.Int32()
|
||||||
@@ -2255,6 +2292,27 @@ enum ToneMapping {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef FilamentRenderCallback
|
||||||
|
= ffi.Pointer<ffi.NativeFunction<FilamentRenderCallbackFunction>>;
|
||||||
|
typedef FilamentRenderCallbackFunction = ffi.Void Function(
|
||||||
|
ffi.Pointer<ffi.Void> owner);
|
||||||
|
typedef DartFilamentRenderCallbackFunction = void Function(
|
||||||
|
ffi.Pointer<ffi.Void> owner);
|
||||||
|
|
||||||
|
enum Projection {
|
||||||
|
Perspective(0),
|
||||||
|
Orthographic(1);
|
||||||
|
|
||||||
|
final int value;
|
||||||
|
const Projection(this.value);
|
||||||
|
|
||||||
|
static Projection fromValue(int value) => switch (value) {
|
||||||
|
0 => Perspective,
|
||||||
|
1 => Orthographic,
|
||||||
|
_ => throw ArgumentError("Unknown value for Projection: $value"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
typedef GizmoPickCallback
|
typedef GizmoPickCallback
|
||||||
= ffi.Pointer<ffi.NativeFunction<GizmoPickCallbackFunction>>;
|
= ffi.Pointer<ffi.NativeFunction<GizmoPickCallbackFunction>>;
|
||||||
typedef GizmoPickCallbackFunction = ffi.Void Function(
|
typedef GizmoPickCallbackFunction = ffi.Void Function(
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import '../../thermion_viewer_base.dart';
|
|||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
import 'callbacks.dart';
|
import 'callbacks.dart';
|
||||||
import 'camera_ffi.dart';
|
import 'ffi_camera.dart';
|
||||||
import 'ffi_view.dart';
|
import 'ffi_view.dart';
|
||||||
|
|
||||||
// ignore: constant_identifier_names
|
// ignore: constant_identifier_names
|
||||||
@@ -180,14 +180,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
nullptr;
|
nullptr;
|
||||||
_viewer = await withPointerCallback(
|
_viewer = await withPointerCallback(
|
||||||
(Pointer<NativeFunction<Void Function(Pointer<TViewer>)>> callback) {
|
(Pointer<NativeFunction<Void Function(Pointer<TViewer>)>> callback) {
|
||||||
Viewer_createOnRenderThread(
|
Viewer_createOnRenderThread(_sharedContext, _driver, uberarchivePtr,
|
||||||
_sharedContext,
|
resourceLoader, _renderCallback, _renderCallbackOwner, callback);
|
||||||
_driver,
|
|
||||||
uberarchivePtr,
|
|
||||||
resourceLoader,
|
|
||||||
_renderCallback,
|
|
||||||
_renderCallbackOwner,
|
|
||||||
callback);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
allocator.free(uberarchivePtr);
|
allocator.free(uberarchivePtr);
|
||||||
@@ -529,8 +523,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
throw Exception("Not yet implemented");
|
throw Exception("Not yet implemented");
|
||||||
}
|
}
|
||||||
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
final pathPtr = path.toNativeUtf8(allocator: allocator).cast<Char>();
|
||||||
var entity = await withIntCallback((callback) => load_glb_render_thread(
|
var entity = await withIntCallback((callback)=> load_glb_render_thread(
|
||||||
_sceneManager!, pathPtr, numInstances, keepData, callback));
|
_sceneManager!, pathPtr, numInstances, keepData, callback));
|
||||||
|
|
||||||
allocator.free(pathPtr);
|
allocator.free(pathPtr);
|
||||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("An error occurred loading the asset at $path");
|
throw Exception("An error occurred loading the asset at $path");
|
||||||
@@ -561,7 +556,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var entity = await withIntCallback((callback) =>
|
var entity = await withIntCallback((callback) =>
|
||||||
load_glb_from_buffer_render_thread(_sceneManager!, data.address,
|
SceneManager_loadGlbFromBufferRenderThread(_sceneManager!, data.address,
|
||||||
data.length, numInstances, keepData, priority, layer, callback));
|
data.length, numInstances, keepData, priority, layer, callback));
|
||||||
|
|
||||||
if (entity == _FILAMENT_ASSET_ERROR) {
|
if (entity == _FILAMENT_ASSET_ERROR) {
|
||||||
@@ -1160,7 +1155,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setToneMapping(ToneMapper mapper) async {
|
Future setToneMapping(ToneMapper mapper) async {
|
||||||
set_tone_mapping_render_thread(_viewer!, mapper.index);
|
final view = await getViewAt(0);
|
||||||
|
view.setToneMapper(mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -1302,7 +1298,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setViewFrustumCulling(bool enabled) async {
|
Future setViewFrustumCulling(bool enabled) async {
|
||||||
set_view_frustum_culling(_viewer!, enabled);
|
var view = await getViewAt(0);
|
||||||
|
view.setFrustumCullingEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -2052,10 +2049,13 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
completer.complete(true);
|
completer.complete(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
Viewer_requestFrameRenderThread(
|
Viewer_requestFrameRenderThread(_viewer!, callback.nativeFunction);
|
||||||
_viewer!, callback.nativeFunction);
|
|
||||||
|
|
||||||
await completer.future.timeout(Duration(seconds: 1));
|
try {
|
||||||
|
await completer.future.timeout(Duration(seconds: 1));
|
||||||
|
} catch (err) {
|
||||||
|
print("WARNING - render call timed out");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Camera> createCamera() async {
|
Future<Camera> createCamera() async {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
export 'src/thermion_viewer_ffi.dart' show ThermionViewerFFI;
|
export 'src/thermion_viewer_ffi.dart' show ThermionViewerFFI;
|
||||||
export 'src/camera_ffi.dart';
|
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
|
|
||||||
import '../thermion_viewer_base.dart';
|
import '../thermion_viewer_base.dart';
|
||||||
|
|
||||||
|
enum Projection { Perspective, Orthographic }
|
||||||
|
|
||||||
abstract class Camera {
|
abstract class Camera {
|
||||||
|
Future setProjection(Projection projection, double left, double right,
|
||||||
|
double bottom, double top, double near, double far);
|
||||||
Future setProjectionMatrixWithCulling(
|
Future setProjectionMatrixWithCulling(
|
||||||
Matrix4 projectionMatrix, double near, double far);
|
Matrix4 projectionMatrix, double near, double far);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'swap_chain.dart';
|
import 'swap_chain.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The viewport currently attached to a [View].
|
||||||
|
///
|
||||||
|
/// The dimensions here are guaranteed to be in physical pixels.
|
||||||
|
///
|
||||||
class Viewport {
|
class Viewport {
|
||||||
final int left;
|
final int left;
|
||||||
final int bottom;
|
final int bottom;
|
||||||
@@ -19,4 +24,7 @@ abstract class View {
|
|||||||
Future setPostProcessing(bool enabled);
|
Future setPostProcessing(bool enabled);
|
||||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa);
|
Future setAntiAliasing(bool msaa, bool fxaa, bool taa);
|
||||||
Future setRenderable(bool renderable, covariant SwapChain swapChain);
|
Future setRenderable(bool renderable, covariant SwapChain swapChain);
|
||||||
|
Future setFrustumCullingEnabled(bool enabled);
|
||||||
|
Future setToneMapper(ToneMapper mapper);
|
||||||
|
Future setBloom(double strength);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -887,7 +887,7 @@ abstract class ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future getActiveCamera();
|
Future<Camera> getActiveCamera();
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
50
thermion_dart/native/include/TCamera.h
Normal file
50
thermion_dart/native/include/TCamera.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace thermion {
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ThermionDartApi.h"
|
||||||
|
|
||||||
|
enum Projection {
|
||||||
|
Perspective,
|
||||||
|
Orthographic
|
||||||
|
};
|
||||||
|
|
||||||
|
// Camera methods
|
||||||
|
EMSCRIPTEN_KEEPALIVE void set_camera_exposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(TCamera *camera, double4x4 matrix);
|
||||||
|
EMSCRIPTEN_KEEPALIVE TCamera *get_camera(TViewer *viewer, EntityId entity);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_model_matrix(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_view_matrix(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_projection_matrix(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_culling_projection_matrix(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE const double *const get_camera_frustum(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void set_camera_projection_matrix(TCamera *camera, double4x4 matrix, double near, double far);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE double get_camera_near(TCamera *camera);
|
||||||
|
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 Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
||||||
|
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, Projection projection, double left, double right,
|
||||||
|
double bottom, double top,
|
||||||
|
double near, double far);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
27
thermion_dart/native/include/ThermionDartAPIUtils.h
Normal file
27
thermion_dart/native/include/ThermionDartAPIUtils.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <math/mat4.h>
|
||||||
|
#include "APIBoundaryTypes.h"
|
||||||
|
|
||||||
|
namespace thermion {
|
||||||
|
|
||||||
|
// Helper function to convert filament::math::mat4 to double4x4
|
||||||
|
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
|
||||||
|
{
|
||||||
|
return double4x4{
|
||||||
|
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
|
||||||
|
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
|
||||||
|
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
|
||||||
|
{mat[3][0], mat[3][1], mat[3][2], mat[3][3]},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to convert double4x4 to filament::math::mat4
|
||||||
|
static filament::math::mat4 convert_double4x4_to_mat4(const double4x4 &d_mat)
|
||||||
|
{
|
||||||
|
return filament::math::mat4{
|
||||||
|
filament::math::float4{float(d_mat.col1[0]), float(d_mat.col1[1]), float(d_mat.col1[2]), float(d_mat.col1[3])},
|
||||||
|
filament::math::float4{float(d_mat.col2[0]), float(d_mat.col2[1]), float(d_mat.col2[2]), float(d_mat.col2[3])},
|
||||||
|
filament::math::float4{float(d_mat.col3[0]), float(d_mat.col3[1]), float(d_mat.col3[2]), float(d_mat.col3[3])},
|
||||||
|
filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,12 +48,15 @@
|
|||||||
|
|
||||||
#include "APIBoundaryTypes.h"
|
#include "APIBoundaryTypes.h"
|
||||||
#include "ResourceBuffer.hpp"
|
#include "ResourceBuffer.hpp"
|
||||||
|
#include "ThermionDartAPIUtils.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
|
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
|
||||||
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer);
|
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer);
|
||||||
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
|
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
|
||||||
@@ -93,7 +96,7 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE void set_background_image_position(TViewer *viewer, float x, float y, bool clamp);
|
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_background_color(TViewer *viewer, const float r, const float g, const float b, const float a);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_bloom(TViewer *viewer, float strength);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath);
|
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath);
|
||||||
EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity);
|
EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity);
|
||||||
EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity);
|
EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity);
|
||||||
@@ -123,14 +126,12 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE void set_light_position(TViewer *viewer, EntityId light, float x, float y, float z);
|
EMSCRIPTEN_KEEPALIVE void set_light_position(TViewer *viewer, EntityId light, float x, float y, float z);
|
||||||
EMSCRIPTEN_KEEPALIVE void set_light_direction(TViewer *viewer, EntityId light, float x, float y, float z);
|
EMSCRIPTEN_KEEPALIVE void set_light_direction(TViewer *viewer, EntityId light, float x, float y, float z);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId load_glb(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData);
|
EMSCRIPTEN_KEEPALIVE EntityId load_glb(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(TSceneManager *sceneManager, const void *const data, size_t length, bool keepData, int priority, int layer);
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
|
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId create_instance(TSceneManager *sceneManager, EntityId id);
|
EMSCRIPTEN_KEEPALIVE EntityId create_instance(TSceneManager *sceneManager, EntityId id);
|
||||||
EMSCRIPTEN_KEEPALIVE int get_instance_count(TSceneManager *sceneManager, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE int get_instance_count(TSceneManager *sceneManager, EntityId entityId);
|
||||||
EMSCRIPTEN_KEEPALIVE void get_instances(TSceneManager *sceneManager, EntityId entityId, EntityId *out);
|
EMSCRIPTEN_KEEPALIVE void get_instances(TSceneManager *sceneManager, EntityId entityId, EntityId *out);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer);
|
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer);
|
||||||
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_frame_interval(TViewer *viewer, float interval);
|
EMSCRIPTEN_KEEPALIVE void set_frame_interval(TViewer *viewer, float interval);
|
||||||
|
|
||||||
@@ -208,6 +209,7 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name);
|
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 void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer);
|
||||||
EMSCRIPTEN_KEEPALIVE TScene* SceneManager_getScene(TSceneManager *tSceneManager);
|
EMSCRIPTEN_KEEPALIVE TScene* SceneManager_getScene(TSceneManager *tSceneManager);
|
||||||
|
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer);
|
||||||
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
|
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
|
||||||
@@ -225,37 +227,7 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE void set_rotation(TSceneManager *sceneManager, EntityId entity, float rads, float x, float y, float z, float w);
|
EMSCRIPTEN_KEEPALIVE void set_rotation(TSceneManager *sceneManager, EntityId entity, float rads, float x, float y, float z, float w);
|
||||||
EMSCRIPTEN_KEEPALIVE void set_scale(TSceneManager *sceneManager, EntityId entity, float scale);
|
EMSCRIPTEN_KEEPALIVE void set_scale(TSceneManager *sceneManager, EntityId entity, float scale);
|
||||||
|
|
||||||
// Camera methods
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_camera_exposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(TCamera *camera, double4x4 matrix);
|
|
||||||
EMSCRIPTEN_KEEPALIVE TCamera *get_camera(TViewer *viewer, EntityId entity);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_model_matrix(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_view_matrix(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_projection_matrix(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_culling_projection_matrix(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE const double *const get_camera_frustum(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_camera_projection_matrix(TCamera *camera, double4x4 matrix, double near, double far);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE double get_camera_near(TCamera *camera);
|
|
||||||
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 Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix);
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
|
|
||||||
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
|
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
|
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
|
||||||
|
|
||||||
// SceneManager
|
// SceneManager
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
#define _DART_FILAMENT_FFI_API_H
|
#define _DART_FILAMENT_FFI_API_H
|
||||||
|
|
||||||
#include "ThermionDartApi.h"
|
#include "ThermionDartApi.h"
|
||||||
|
#include "TView.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
namespace thermion {
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
@@ -33,6 +35,10 @@ extern "C"
|
|||||||
void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
|
void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
|
||||||
void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)());
|
void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)());
|
||||||
|
|
||||||
|
void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping);
|
||||||
|
void View_setBloomRenderThread(TView *tView, double bloom);
|
||||||
|
|
||||||
|
|
||||||
void destroy_filament_viewer_render_thread(TViewer *viewer);
|
void destroy_filament_viewer_render_thread(TViewer *viewer);
|
||||||
|
|
||||||
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
||||||
@@ -43,13 +49,11 @@ extern "C"
|
|||||||
void clear_background_image_render_thread(TViewer *viewer);
|
void clear_background_image_render_thread(TViewer *viewer);
|
||||||
void set_background_image_render_thread(TViewer *viewer, const char *path, bool fillHeight, void (*onComplete)());
|
void set_background_image_render_thread(TViewer *viewer, const char *path, bool fillHeight, void (*onComplete)());
|
||||||
void set_background_image_position_render_thread(TViewer *viewer, float x, float y, bool clamp);
|
void set_background_image_position_render_thread(TViewer *viewer, float x, float y, bool clamp);
|
||||||
void set_tone_mapping_render_thread(TViewer *viewer, int toneMapping);
|
|
||||||
void set_bloom_render_thread(TViewer *viewer, float strength);
|
|
||||||
void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
|
void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
|
||||||
void remove_skybox_render_thread(TViewer *viewer);
|
void remove_skybox_render_thread(TViewer *viewer);
|
||||||
|
|
||||||
|
void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId));
|
||||||
void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
|
void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
|
||||||
void load_glb_from_buffer_render_thread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId));
|
|
||||||
void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
|
void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
|
||||||
void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
|
void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
|
||||||
void remove_entity_render_thread(TViewer *viewer, EntityId asset, void (*callback)());
|
void remove_entity_render_thread(TViewer *viewer, EntityId asset, void (*callback)());
|
||||||
@@ -103,6 +107,7 @@ extern "C"
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _DART_FILAMENT_FFI_API_H
|
#endif // _DART_FILAMENT_FFI_API_H
|
||||||
|
|||||||
@@ -783,7 +783,6 @@ namespace thermion
|
|||||||
///
|
///
|
||||||
View *FilamentViewer::getViewAt(int32_t index)
|
View *FilamentViewer::getViewAt(int32_t index)
|
||||||
{
|
{
|
||||||
Log("Getting view at %d", index);
|
|
||||||
if (index < _views.size())
|
if (index < _views.size())
|
||||||
{
|
{
|
||||||
return _views[index];
|
return _views[index];
|
||||||
|
|||||||
84
thermion_dart/native/src/TCamera.cpp
Normal file
84
thermion_dart/native/src/TCamera.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include <filament/View.h>
|
||||||
|
#include <filament/Viewport.h>
|
||||||
|
#include <filament/Engine.h>
|
||||||
|
#include <filament/ToneMapper.h>
|
||||||
|
#include <filament/ColorGrading.h>
|
||||||
|
#include <filament/Camera.h>
|
||||||
|
#include <utils/Entity.h>
|
||||||
|
|
||||||
|
#include "ThermionDartApi.h"
|
||||||
|
#include "TCamera.h"
|
||||||
|
#include "ThermionDartAPIUtils.h"
|
||||||
|
|
||||||
|
#include "Log.hpp"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace thermion
|
||||||
|
{
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
using namespace filament;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 utils::Entity::smuggle(camera->getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const tCamera)
|
||||||
|
{
|
||||||
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
|
return camera->getFocalLength() * 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 void Camera_setProjection(TCamera *const tCamera, Projection projection, double left, double right,
|
||||||
|
double bottom, double top,
|
||||||
|
double near, double far)
|
||||||
|
{
|
||||||
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
|
filament::Camera::Projection filamentProjection;
|
||||||
|
switch(projection) {
|
||||||
|
case Projection::Orthographic:
|
||||||
|
filamentProjection = filament::Camera::Projection::ORTHO;
|
||||||
|
case Projection::Perspective:
|
||||||
|
filamentProjection = filament::Camera::Projection::PERSPECTIVE;
|
||||||
|
}
|
||||||
|
camera->setProjection(filamentProjection, left, right, bottom, top, near, far);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "TView.h"
|
#include "TView.h"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
namespace thermion {
|
namespace thermion {
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|||||||
@@ -23,27 +23,6 @@ extern "C"
|
|||||||
|
|
||||||
#include "ThermionDartApi.h"
|
#include "ThermionDartApi.h"
|
||||||
|
|
||||||
// Helper function to convert filament::math::mat4 to double4x4
|
|
||||||
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
|
|
||||||
{
|
|
||||||
return double4x4{
|
|
||||||
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
|
|
||||||
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
|
|
||||||
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
|
|
||||||
{mat[3][0], mat[3][1], mat[3][2], mat[3][3]},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to convert double4x4 to filament::math::mat4
|
|
||||||
static filament::math::mat4 convert_double4x4_to_mat4(const double4x4 &d_mat)
|
|
||||||
{
|
|
||||||
return filament::math::mat4{
|
|
||||||
filament::math::float4{float(d_mat.col1[0]), float(d_mat.col1[1]), float(d_mat.col1[2]), float(d_mat.col1[3])},
|
|
||||||
filament::math::float4{float(d_mat.col2[0]), float(d_mat.col2[1]), float(d_mat.col2[2]), float(d_mat.col2[3])},
|
|
||||||
filament::math::float4{float(d_mat.col3[0]), float(d_mat.col3[1]), float(d_mat.col3[2]), float(d_mat.col3[3])},
|
|
||||||
filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}};
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *context, const void *const loader, void *const platform, const char *uberArchivePath)
|
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *context, const void *const loader, void *const platform, const char *uberArchivePath)
|
||||||
{
|
{
|
||||||
const auto *loaderImpl = new ResourceLoaderWrapperImpl((ResourceLoaderWrapper *)loader);
|
const auto *loaderImpl = new ResourceLoaderWrapperImpl((ResourceLoaderWrapper *)loader);
|
||||||
@@ -183,7 +162,7 @@ extern "C"
|
|||||||
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
|
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(TSceneManager *sceneManager, const void *const data, size_t length, bool keepData, int priority, int layer)
|
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer)
|
||||||
{
|
{
|
||||||
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer);
|
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer);
|
||||||
}
|
}
|
||||||
@@ -1064,47 +1043,6 @@ extern "C"
|
|||||||
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
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)
|
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "ThermionDartRenderThreadApi.h"
|
#include "ThermionDartRenderThreadApi.h"
|
||||||
#include "FilamentViewer.hpp"
|
#include "FilamentViewer.hpp"
|
||||||
|
#include "TView.h"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include "ThreadPool.hpp"
|
#include "ThreadPool.hpp"
|
||||||
#include "filament/LightManager.h"
|
#include "filament/LightManager.h"
|
||||||
@@ -328,7 +329,7 @@ extern "C"
|
|||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_glb_from_buffer_render_thread(TSceneManager *sceneManager,
|
void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager,
|
||||||
const uint8_t *const data,
|
const uint8_t *const data,
|
||||||
size_t length,
|
size_t length,
|
||||||
int numInstances,
|
int numInstances,
|
||||||
@@ -340,7 +341,7 @@ extern "C"
|
|||||||
std::packaged_task<EntityId()> lambda(
|
std::packaged_task<EntityId()> lambda(
|
||||||
[=]() mutable
|
[=]() mutable
|
||||||
{
|
{
|
||||||
auto entity = load_glb_from_buffer(sceneManager, data, length, keepData, priority, layer);
|
auto entity = SceneManager_loadGlbFromBuffer(sceneManager, data, length, keepData, priority, layer);
|
||||||
callback(entity);
|
callback(entity);
|
||||||
return entity;
|
return entity;
|
||||||
});
|
});
|
||||||
@@ -562,6 +563,24 @@ extern "C"
|
|||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping) {
|
||||||
|
std::packaged_task<void()> lambda(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
View_setToneMapping(tView, tEngine, toneMapping);
|
||||||
|
});
|
||||||
|
auto fut = _rl->add_task(lambda);
|
||||||
|
}
|
||||||
|
|
||||||
|
void View_setBloomRenderThread(TView *tView, double bloom) {
|
||||||
|
std::packaged_task<void()> lambda(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
View_setBloom(tView, bloom);
|
||||||
|
});
|
||||||
|
auto fut = _rl->add_task(lambda);
|
||||||
|
}
|
||||||
|
|
||||||
void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)())
|
void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)())
|
||||||
{
|
{
|
||||||
std::packaged_task<void()> lambda(
|
std::packaged_task<void()> lambda(
|
||||||
|
|||||||
@@ -76,6 +76,17 @@ void main() async {
|
|||||||
print(frustum.plane5.constant);
|
print(frustum.plane5.constant);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('set orthographic projection', () async {
|
||||||
|
var viewer = await testHelper.createViewer(
|
||||||
|
bg: kRed, cameraPosition: Vector3(0, 0, 4));
|
||||||
|
var camera = await viewer.getMainCamera();
|
||||||
|
await viewer.createGeometry(GeometryHelper.cube());
|
||||||
|
|
||||||
|
await camera.setProjection(Projection.Orthographic, -0.05, 0.05, -0.05, 0.05, 0.05, 10000);
|
||||||
|
await testHelper.capture(
|
||||||
|
viewer, "camera_set_orthographic_projection");
|
||||||
|
});
|
||||||
|
|
||||||
test('set custom projection/culling matrix', () async {
|
test('set custom projection/culling matrix', () async {
|
||||||
var viewer = await testHelper.createViewer(
|
var viewer = await testHelper.createViewer(
|
||||||
bg: kRed, cameraPosition: Vector3(0, 0, 4));
|
bg: kRed, cameraPosition: Vector3(0, 0, 4));
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class TestHelper {
|
|||||||
var viewer = ThermionViewerFFI(resourceLoader: resourceLoader.cast<Void>());
|
var viewer = ThermionViewerFFI(resourceLoader: resourceLoader.cast<Void>());
|
||||||
|
|
||||||
await viewer.initialized;
|
await viewer.initialized;
|
||||||
swapChain = await viewer.createSwapChain(
|
swapChain = await viewer.createHeadlessSwapChain(
|
||||||
viewportDimensions.width, viewportDimensions.height);
|
viewportDimensions.width, viewportDimensions.height);
|
||||||
|
|
||||||
await viewer.updateViewportAndCameraProjection(
|
await viewer.updateViewportAndCameraProjection(
|
||||||
|
|||||||
@@ -9,30 +9,40 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_platform_in
|
|||||||
/// Call [createViewerWithOptions] to create an instance of [ThermionViewer].
|
/// Call [createViewerWithOptions] to create an instance of [ThermionViewer].
|
||||||
///
|
///
|
||||||
class ThermionFlutterPlugin {
|
class ThermionFlutterPlugin {
|
||||||
|
|
||||||
ThermionFlutterPlugin._();
|
ThermionFlutterPlugin._();
|
||||||
|
|
||||||
static bool _initializing = false;
|
static bool _initializing = false;
|
||||||
|
|
||||||
static ThermionViewer? _viewer;
|
static ThermionViewer? _viewer;
|
||||||
|
|
||||||
|
static ThermionFlutterOptions? options;
|
||||||
|
|
||||||
static Future<ThermionViewer> createViewer(
|
static Future<ThermionViewer> createViewer(
|
||||||
{ThermionFlutterOptions options =
|
{ThermionFlutterOptions options =
|
||||||
const ThermionFlutterOptions.empty()}) async {
|
const ThermionFlutterOptions.empty()}) async {
|
||||||
|
|
||||||
if (_initializing) {
|
if (_initializing) {
|
||||||
throw Exception("Existing call to createViewer has not completed.");
|
throw Exception("Existing call to createViewer has not completed.");
|
||||||
}
|
}
|
||||||
_initializing = true;
|
_initializing = true;
|
||||||
|
|
||||||
|
if (_viewer != null) {
|
||||||
|
throw Exception(
|
||||||
|
"Instance of ThermionViewer has already been created. Ensure you call dispose() on that instance.");
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options;
|
||||||
|
|
||||||
_viewer =
|
_viewer =
|
||||||
await ThermionFlutterPlatform.instance.createViewer(options: options);
|
await ThermionFlutterPlatform.instance.createViewer(options: options);
|
||||||
|
|
||||||
|
var camera = await _viewer!.getActiveCamera();
|
||||||
|
camera.setLensProjection();
|
||||||
|
|
||||||
_viewer!.onDispose(() async {
|
_viewer!.onDispose(() async {
|
||||||
_viewer = null;
|
_viewer = null;
|
||||||
|
ThermionFlutterPlugin.options = null;
|
||||||
});
|
});
|
||||||
_initializing = false;
|
_initializing = false;
|
||||||
return _viewer!;
|
return _viewer!;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,32 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dar
|
|||||||
import 'package:vector_math/vector_math_64.dart' hide Colors;
|
import 'package:vector_math/vector_math_64.dart' hide Colors;
|
||||||
|
|
||||||
class ThermionTextureWidget extends StatefulWidget {
|
class ThermionTextureWidget extends StatefulWidget {
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
final t.View view;
|
final t.View view;
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
final Widget? initial;
|
final Widget? initial;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A callback that will be invoked whenever this widget (and the underlying texture is resized).
|
||||||
|
///
|
||||||
|
final Future Function(Size size, t.View view, double pixelRatio)? onResize;
|
||||||
|
|
||||||
const ThermionTextureWidget(
|
const ThermionTextureWidget(
|
||||||
{super.key, required this.viewer, required this.view, this.initial});
|
{super.key,
|
||||||
|
required this.viewer,
|
||||||
|
required this.view,
|
||||||
|
this.initial,
|
||||||
|
this.onResize});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
@@ -54,9 +72,16 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
.createTexture(widget.view, width, height);
|
.createTexture(widget.view, width, height);
|
||||||
|
|
||||||
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
||||||
var camera = await widget.view.getCamera();
|
|
||||||
await camera.setLensProjection(
|
try {
|
||||||
aspect: _texture!.width / _texture!.height);
|
await widget.onResize?.call(
|
||||||
|
Size(_texture!.width.toDouble(), _texture!.height.toDouble()),
|
||||||
|
widget.view,
|
||||||
|
dpr);
|
||||||
|
} catch (err, st) {
|
||||||
|
print(err);
|
||||||
|
print(st);
|
||||||
|
}
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@@ -124,7 +149,9 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
|
|
||||||
_resizing.add(completer.future);
|
_resizing.add(completer.future);
|
||||||
|
|
||||||
newSize *= MediaQuery.of(context).devicePixelRatio;
|
final dpr = MediaQuery.of(context).devicePixelRatio;
|
||||||
|
|
||||||
|
newSize *= dpr;
|
||||||
|
|
||||||
var newWidth = newSize.width.ceil();
|
var newWidth = newSize.width.ceil();
|
||||||
var newHeight = newSize.height.ceil();
|
var newHeight = newSize.height.ceil();
|
||||||
@@ -136,11 +163,13 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
||||||
var camera = await widget.view.getCamera();
|
|
||||||
await camera.setLensProjection(
|
await widget.onResize?.call(
|
||||||
aspect: _texture!.width.toDouble() / _texture!.height.toDouble());
|
Size(_texture!.width.toDouble(), _texture!.height.toDouble()),
|
||||||
|
widget.view,
|
||||||
|
dpr);
|
||||||
|
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -169,108 +198,3 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// class _ThermionWidgetState extends State<ThermionWidget> {
|
|
||||||
|
|
||||||
// ThermionFlutterTexture? _texture;
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// void initState() {
|
|
||||||
// WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
|
||||||
// await widget.viewer.initialized;
|
|
||||||
// widget.viewer.onDispose(() async {
|
|
||||||
// _rendering = false;
|
|
||||||
|
|
||||||
// if (_texture != null) {
|
|
||||||
// var texture = _texture;
|
|
||||||
// _texture = null;
|
|
||||||
// if (mounted) {
|
|
||||||
// setState(() {});
|
|
||||||
// }
|
|
||||||
// await ThermionFlutterPlugin.destroyTexture(texture!);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// var dpr = MediaQuery.of(context).devicePixelRatio;
|
|
||||||
|
|
||||||
// var size = ((context.findRenderObject()) as RenderBox).size;
|
|
||||||
// _texture = await ThermionFlutterPlugin.createTexture(
|
|
||||||
// size.width, size.height, 0, 0, dpr);
|
|
||||||
|
|
||||||
// if (mounted) {
|
|
||||||
// setState(() {});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// _requestFrame();
|
|
||||||
// });
|
|
||||||
// super.initState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bool _rendering = false;
|
|
||||||
|
|
||||||
// void _requestFrame() {
|
|
||||||
// WidgetsBinding.instance.scheduleFrameCallback((d) async {
|
|
||||||
// if (!_rendering) {
|
|
||||||
// _rendering = true;
|
|
||||||
// await widget.viewer.requestFrame();
|
|
||||||
// _rendering = false;
|
|
||||||
// }
|
|
||||||
// _requestFrame();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// bool _resizing = false;
|
|
||||||
// Timer? _resizeTimer;
|
|
||||||
|
|
||||||
// Future _resizeTexture(Size newSize) async {
|
|
||||||
// _resizeTimer?.cancel();
|
|
||||||
// _resizeTimer = Timer(const Duration(milliseconds: 500), () async {
|
|
||||||
// if (_resizing || !mounted) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _resizeTimer!.cancel();
|
|
||||||
// _resizing = true;
|
|
||||||
|
|
||||||
// if (!mounted) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var dpr = MediaQuery.of(context).devicePixelRatio;
|
|
||||||
|
|
||||||
// _texture.resize(newSize.width.ceil(), newSize.height.ceil(), 0, 0, dpr);
|
|
||||||
// setState(() {});
|
|
||||||
// _resizing = false;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// if (_texture == null || _resizing) {
|
|
||||||
// return widget.initial ??
|
|
||||||
// Container(
|
|
||||||
// color:
|
|
||||||
// kIsWeb ? const Color.fromARGB(0, 170, 129, 129) : Colors.red);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var textureWidget = Texture(
|
|
||||||
// key: ObjectKey("texture_${_texture!.flutterId}"),
|
|
||||||
// textureId: _texture!.flutterId!,
|
|
||||||
// filterQuality: FilterQuality.none,
|
|
||||||
// freeze: false,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// return ResizeObserver(
|
|
||||||
// onResized: _resizeTexture,
|
|
||||||
// child: Stack(children: [
|
|
||||||
// Positioned.fill(
|
|
||||||
// child: Platform.isLinux || Platform.isWindows
|
|
||||||
// ? Transform(
|
|
||||||
// alignment: Alignment.center,
|
|
||||||
// transform: Matrix4.rotationX(
|
|
||||||
// pi), // TODO - this rotation is due to OpenGL texture coordinate working in a different space from Flutter, can we move this to the C++ side somewhere?
|
|
||||||
// child: textureWidget)
|
|
||||||
// : textureWidget)
|
|
||||||
// ]));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -8,6 +8,16 @@ import 'package:thermion_flutter_web/thermion_flutter_web_options.dart';
|
|||||||
import 'package:thermion_dart/src/viewer/src/shared_types/view.dart' as t;
|
import 'package:thermion_dart/src/viewer/src/shared_types/view.dart' as t;
|
||||||
import 'thermion_widget_windows.dart';
|
import 'thermion_widget_windows.dart';
|
||||||
|
|
||||||
|
Future kDefaultResizeCallback(Size size, t.View view, double pixelRatio) async {
|
||||||
|
var camera = await view.getCamera();
|
||||||
|
var near = await camera.getNear();
|
||||||
|
var far = await camera.getCullingFar();
|
||||||
|
var focalLength = await camera.getFocalLength();
|
||||||
|
|
||||||
|
await camera.setLensProjection(near:near, far:far, focalLength: focalLength,
|
||||||
|
aspect: size.width.toDouble() / size.height.toDouble());
|
||||||
|
}
|
||||||
|
|
||||||
class ThermionWidget extends StatefulWidget {
|
class ThermionWidget extends StatefulWidget {
|
||||||
///
|
///
|
||||||
/// The viewer.
|
/// The viewer.
|
||||||
@@ -15,14 +25,25 @@ class ThermionWidget extends StatefulWidget {
|
|||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The view.
|
/// The [View] associated with this widget. If null, the default View will be used.
|
||||||
///
|
///
|
||||||
final t.View? view;
|
final t.View? view;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The options to use when creating this widget.
|
/// A callback to invoke whenever this widget and the underlying surface are
|
||||||
|
/// resized. If a callback is not explicitly provided, the default callback
|
||||||
|
/// will be run, which changes the aspect ratio for the active camera in
|
||||||
|
/// the View managed by this widget. If you specify your own callback,
|
||||||
|
/// you probably want to preserve this behaviour (otherwise the aspect ratio)
|
||||||
|
/// will be incorrect.
|
||||||
|
///
|
||||||
|
/// To completely disable the resize callback, pass [null].
|
||||||
|
///
|
||||||
|
/// IMPORTANT - size is specified in physical pixels, not logical pixels.
|
||||||
|
/// If you need to work with Flutter dimensions, divide [size] by
|
||||||
|
/// [pixelRatio].
|
||||||
///
|
///
|
||||||
final ThermionFlutterOptions? options;
|
final Future Function(Size size, t.View view, double pixelRatio)? onResize;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The content to render before the texture widget is available.
|
/// The content to render before the texture widget is available.
|
||||||
@@ -31,7 +52,11 @@ class ThermionWidget extends StatefulWidget {
|
|||||||
final Widget? initial;
|
final Widget? initial;
|
||||||
|
|
||||||
const ThermionWidget(
|
const ThermionWidget(
|
||||||
{Key? key, this.initial, required this.viewer, this.view, this.options})
|
{Key? key,
|
||||||
|
this.initial,
|
||||||
|
required this.viewer,
|
||||||
|
this.view,
|
||||||
|
this.onResize = kDefaultResizeCallback})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -66,7 +91,7 @@ class _ThermionWidgetState extends State<ThermionWidget> {
|
|||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
return ThermionWidgetWeb(
|
return ThermionWidgetWeb(
|
||||||
viewer: widget.viewer,
|
viewer: widget.viewer,
|
||||||
options: widget.options as ThermionFlutterWebOptions);
|
options: ThermionFlutterPlugin.options as ThermionFlutterWebOptions?);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
@@ -77,6 +102,7 @@ class _ThermionWidgetState extends State<ThermionWidget> {
|
|||||||
key: ObjectKey(view!),
|
key: ObjectKey(view!),
|
||||||
initial: widget.initial,
|
initial: widget.initial,
|
||||||
viewer: widget.viewer,
|
viewer: widget.viewer,
|
||||||
view: view!);
|
view: view!,
|
||||||
|
onResize: widget.onResize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ library;
|
|||||||
export 'src/thermion_widget.dart';
|
export 'src/thermion_widget.dart';
|
||||||
export 'src/thermion_listener_widget.dart';
|
export 'src/thermion_listener_widget.dart';
|
||||||
export 'src/camera/camera_selector_widget.dart';
|
export 'src/camera/camera_selector_widget.dart';
|
||||||
|
export 'src/camera/camera_orientation_widget.dart';
|
||||||
|
|||||||
Reference in New Issue
Block a user