diff --git a/example/lib/camera_matrix_overlay.dart b/example/lib/camera_matrix_overlay.dart index 2b3cb3ee..ae04c45f 100644 --- a/example/lib/camera_matrix_overlay.dart +++ b/example/lib/camera_matrix_overlay.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_filament/filament_controller.dart'; +import 'package:vector_math/vector_math_64.dart' as v; class CameraMatrixOverlay extends StatefulWidget { final FilamentController controller; @@ -43,6 +44,7 @@ class _CameraMatrixOverlayState extends State { projMatrix.storage.map((v) => v.toStringAsFixed(2)).join(","); _cameraCullingProjectionMatrix = cullingMatrix.storage.map((v) => v.toStringAsFixed(2)).join(","); + _getFrustum(); } setState(() {}); @@ -55,6 +57,12 @@ class _CameraMatrixOverlayState extends State { } } + v.Frustum? _frustum; + + void _getFrustum() async { + _frustum = await widget.controller.getCameraFrustum(); + } + @override void initState() { super.initState(); @@ -87,17 +95,50 @@ class _CameraMatrixOverlayState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, - children: [ - Text("Camera position : $_cameraPosition $_cameraRotation", - style: const TextStyle(color: Colors.white, fontSize: 12)), - widget.showProjectionMatrices - ? Text("Projection matrix : $_cameraProjectionMatrix", - style: const TextStyle(color: Colors.white, fontSize: 12)) - : Container(), - widget.showProjectionMatrices - ? Text("Culling matrix : $_cameraCullingProjectionMatrix", - style: const TextStyle(color: Colors.white, fontSize: 12)) - : Container(), - ])); + children: [ + Text("Camera position : $_cameraPosition $_cameraRotation", + style: + const TextStyle(color: Colors.white, fontSize: 10)), + // widget.showProjectionMatrices + // ? Text("Projection matrix : $_cameraProjectionMatrix", + // style: const TextStyle(color: Colors.white, fontSize: 12)) + // : Container(), + // widget.showProjectionMatrices + // ? Text("Culling matrix : $_cameraCullingProjectionMatrix", + // style: const TextStyle(color: Colors.white, fontSize: 12)) + // : Container(), + widget.showProjectionMatrices + ? const Text("Frustum matrix", + style: TextStyle(color: Colors.white, fontSize: 10)) + : Container() + ] + + (_frustum == null + ? [] + : [ + _frustum!.plane0, + _frustum!.plane1, + _frustum!.plane2, + _frustum!.plane3, + _frustum!.plane4, + _frustum!.plane5 + ] + .map((plane) => Row( + children: [ + plane.normal.x, + plane.normal.y, + plane.normal.z, + plane.constant + ] + .map((v) => Text( + v.toStringAsFixed(2) + " ", + style: const TextStyle( + color: Colors.white, + fontSize: 10), + textAlign: TextAlign.center, + )) + .cast() + .toList())) + .cast() + .toList()))); } } diff --git a/example/lib/menus/camera_submenu.dart b/example/lib/menus/camera_submenu.dart index 988edfdc..9ab4464c 100644 --- a/example/lib/menus/camera_submenu.dart +++ b/example/lib/menus/camera_submenu.dart @@ -15,8 +15,20 @@ class CameraSubmenu extends StatefulWidget { } class _CameraSubmenuState extends State { - double _near = 0.05; - double _far = 1000.0; + double? _near; + double? _far; + + @override + void initState() { + super.initState(); + widget.controller.getCameraCullingNear().then((v) { + _near = v; + widget.controller.getCameraCullingFar().then((v) { + _far = v; + setState(() {}); + }); + }); + } final _menuController = MenuController(); @@ -30,7 +42,7 @@ class _CameraSubmenuState extends State { print("Set to ${ExampleWidgetState.showProjectionMatrices}"); }, child: Text( - '${ExampleWidgetState.showProjectionMatrices.value ? "Hide" : "Display"} camera projection/culling projection matrices', + '${ExampleWidgetState.showProjectionMatrices.value ? "Hide" : "Display"} camera frustum', style: TextStyle( fontWeight: ExampleWidgetState.showProjectionMatrices.value ? FontWeight.bold @@ -54,7 +66,9 @@ class _CameraSubmenuState extends State { .map((v) => MenuItemButton( onPressed: () { _near = v; - widget.controller.setCameraCulling(_near, _far); + print("Setting camera culling to $_near $_far!"); + + widget.controller.setCameraCulling(_near!, _far!); }, child: Text( v.toStringAsFixed(2), @@ -67,7 +81,8 @@ class _CameraSubmenuState extends State { .map((v) => MenuItemButton( onPressed: () { _far = v; - widget.controller.setCameraCulling(_near, _far); + print("Setting camera culling to $_near! $_far"); + widget.controller.setCameraCulling(_near!, _far!); }, child: Text( v.toStringAsFixed(2), @@ -79,7 +94,14 @@ class _CameraSubmenuState extends State { onPressed: () async { widget.controller.setCameraPosition(1.0, 1.0, -1.0); }, - child: const Text('Move to 1, 1, -1'), + child: const Text('Set position to 1, 1, -1 (leave rotation as-is)'), + ), + MenuItemButton( + onPressed: () async { + widget.controller.setCameraPosition(0.0, 0.0, 0.0); + widget.controller.setCameraRotation(0, 0.0, 1.0, 0.0); + }, + child: const Text('Move to 0,0,0, facing towards 0,0,-1'), ), MenuItemButton( onPressed: () async { @@ -130,38 +152,6 @@ class _CameraSubmenuState extends State { }); }, child: const Text("Get projection matrix")), - MenuItemButton( - closeOnActivate: false, - onPressed: () async { - var frustum = await widget.controller.getCameraFrustum(); - var normalString = [ - frustum.plane0, - frustum.plane1, - frustum.plane2, - frustum.plane3, - frustum.plane4, - frustum.plane5 - ] - .map((plane) => - plane.normal.storage - .map((v) => v.toStringAsFixed(2)) - .join(",") + - ",${plane.constant}") - .join("\n"); - showDialog( - context: context, - builder: (ctx) { - return Center( - child: Container( - height: 300, - width: 300, - color: Colors.white, - child: - Text("Frustum plane normals : $normalString "))); - }); - _menuController.close(); - }, - child: const Text("Get frustum")), SubmenuButton( menuChildren: ManipulatorMode.values.map((mm) { return MenuItemButton( @@ -233,6 +223,9 @@ class _CameraSubmenuState extends State { @override Widget build(BuildContext context) { + if (_near == null || _far == null) { + return Container(); + } return SubmenuButton( controller: _menuController, menuChildren: _cameraMenu(), diff --git a/ios/include/FilamentViewer.hpp b/ios/include/FilamentViewer.hpp index 81c443b6..476b9b82 100644 --- a/ios/include/FilamentViewer.hpp +++ b/ios/include/FilamentViewer.hpp @@ -109,6 +109,8 @@ namespace polyvox void setCameraProjectionMatrix(const double *const matrix, double near, double far); void setCameraFocalLength(float focalLength); void setCameraCulling(double near, double far); + double getCameraCullingNear(); + double getCameraCullingFar(); void setCameraFocusDistance(float focusDistance); void setCameraManipulatorOptions(filament::camutils::Mode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed); void grabBegin(float x, float y, bool pan); diff --git a/ios/include/FlutterFilamentApi.h b/ios/include/FlutterFilamentApi.h index a3d2af49..faed965c 100644 --- a/ios/include/FlutterFilamentApi.h +++ b/ios/include/FlutterFilamentApi.h @@ -157,6 +157,8 @@ extern "C" FLUTTER_PLUGIN_EXPORT const double *const get_camera_projection_matrix(const void *const viewer); FLUTTER_PLUGIN_EXPORT void set_camera_projection_matrix(const void *const viewer, const double *const matrix, double near, double far); FLUTTER_PLUGIN_EXPORT void set_camera_culling(const void *const viewer, double near, double far); + FLUTTER_PLUGIN_EXPORT double get_camera_culling_near(const void *const viewer); + FLUTTER_PLUGIN_EXPORT double get_camera_culling_far(const void *const viewer); FLUTTER_PLUGIN_EXPORT const double *const get_camera_culling_projection_matrix(const void *const viewer); FLUTTER_PLUGIN_EXPORT const double *const get_camera_frustum(const void *const viewer); FLUTTER_PLUGIN_EXPORT void set_camera_focal_length(const void *const viewer, float focalLength); diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index f9360bba..6a47d37f 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -757,8 +757,17 @@ namespace polyvox Camera &cam = _view->getCamera(); _near = near; _far = far; - cam.setLensProjection(_cameraFocalLength, 1.0f, _near, - _far); + cam.setLensProjection(_cameraFocalLength, 1.0f, _near, _far); + Log("Set lens projection to focal length %f, near %f and far %f", _cameraFocalLength, _near, _far); + } + + double FilamentViewer::getCameraCullingNear() { + Camera &cam = _view->getCamera(); + return cam.getNear(); + } + double FilamentViewer::getCameraCullingFar() { + Camera &cam = _view->getCamera(); + return cam.getCullingFar(); } /// diff --git a/ios/src/FlutterFilamentApi.cpp b/ios/src/FlutterFilamentApi.cpp index 51f1b679..c22a9ab9 100644 --- a/ios/src/FlutterFilamentApi.cpp +++ b/ios/src/FlutterFilamentApi.cpp @@ -158,6 +158,14 @@ extern "C" ((FilamentViewer *)viewer)->setCameraCulling(near, far); } + double get_camera_culling_near(const void *const viewer) { + return ((FilamentViewer*)viewer)->getCameraCullingNear(); + } + + double get_camera_culling_far(const void *const viewer) { + return ((FilamentViewer*)viewer)->getCameraCullingFar(); + } + const double *const get_camera_frustum(const void *const viewer) { const auto frustum = ((FilamentViewer *)viewer)->getCameraFrustum(); @@ -165,10 +173,11 @@ extern "C" double *array = (double *)calloc(24, sizeof(double)); for (int i = 0; i < 6; i++) { - array[i * 4] = planes[i].x; - array[i * 4 + 1] = planes[i].y; - array[i * 4 + 2] = planes[i].z; - array[i * 4 + 3] = planes[i].w; + auto plane = planes[i]; + array[i * 4] = double(plane.x); + array[i * 4 + 1] = double(plane.y); + array[i * 4 + 2] = double(plane.z); + array[i * 4 + 3] = double(plane.w); } return array; diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index 203ede7f..71dab108 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -345,10 +345,20 @@ abstract class FilamentController { Future setCameraFocalLength(double focalLength); /// - /// Sets the near/far culling planes for the active camera. Default values are 0.05/1000.0. See Camera.h for details. + /// Sets the distance (in world units) to the near/far planes for the active camera. Default values are 0.05/1000.0. See Camera.h for details. /// Future setCameraCulling(double near, double far); + /// + /// Get the distance (in world units) to the near culling plane for the active camera. + /// + Future getCameraCullingNear(); + + /// + /// Get the distance (in world units) to the far culling plane for the active camera. + /// + Future getCameraCullingFar(); + /// /// Sets the focus distance for the camera. /// diff --git a/lib/filament_controller_ffi.dart b/lib/filament_controller_ffi.dart index f3234ea7..465e493e 100644 --- a/lib/filament_controller_ffi.dart +++ b/lib/filament_controller_ffi.dart @@ -867,6 +867,16 @@ class FilamentControllerFFI extends FilamentController { set_camera_culling(_viewer!, near, far); } + @override + Future getCameraCullingNear() async { + return get_camera_culling_near(_viewer!); + } + + @override + Future getCameraCullingFar() async { + return get_camera_culling_far(_viewer!); + } + @override Future setCameraFocusDistance(double focusDistance) async { if (_viewer == null) { @@ -1147,10 +1157,7 @@ class FilamentControllerFFI extends FilamentController { } var arrayPtr = get_camera_frustum(_viewer!); var doubleList = arrayPtr.asTypedList(24); - var planeNormals = []; - for (int i = 0; i < 6; i++) { - planeNormals.add(Vector3.array(doubleList.sublist(i * 3, (i + 1) * 3))); - } + print(doubleList); var frustum = Frustum(); frustum.plane0.setFromComponents( @@ -1165,7 +1172,7 @@ class FilamentControllerFFI extends FilamentController { doubleList[16], doubleList[17], doubleList[18], doubleList[19]); frustum.plane5.setFromComponents( doubleList[20], doubleList[21], doubleList[22], doubleList[23]); - + flutter_filament_free(arrayPtr.cast()); return frustum; } diff --git a/lib/generated_bindings.dart b/lib/generated_bindings.dart index 51e69b8d..aa139ff6 100644 --- a/lib/generated_bindings.dart +++ b/lib/generated_bindings.dart @@ -651,6 +651,18 @@ external void set_camera_culling( double far, ); +@ffi.Native)>( + symbol: 'get_camera_culling_near', assetId: 'flutter_filament_plugin') +external double get_camera_culling_near( + ffi.Pointer viewer, +); + +@ffi.Native)>( + symbol: 'get_camera_culling_far', assetId: 'flutter_filament_plugin') +external double get_camera_culling_far( + ffi.Pointer viewer, +); + @ffi.Native Function(ffi.Pointer)>( symbol: 'get_camera_culling_projection_matrix', assetId: 'flutter_filament_plugin')