add setCameraCulling method to set near/far culling plane and return vector_math:Frustum from planes returned by get_camera_frustum

This commit is contained in:
Nick Fisher
2023-11-09 15:08:34 +08:00
parent 76f723c497
commit f2a458b9ca
11 changed files with 227 additions and 104 deletions

View File

@@ -335,10 +335,15 @@ abstract class FilamentController {
Future setBloom(double bloom);
///
/// Sets the focal length of the camera.
/// Sets the focal length of the camera. Default value is 28.0.
///
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.
///
Future setCameraCulling(double near, double far);
///
/// Sets the focus distance for the camera.
///
@@ -370,7 +375,8 @@ abstract class FilamentController {
Future<Matrix4> getCameraCullingProjectionMatrix();
///
/// Get the camera's culling frustum in world space. Returns six Vector4s defining the left, right, bottom, top, far and near planes respectively. See Camera.h and Frustum.h for more details.
/// Get the camera's culling frustum in world space. Returns a (vector_math) [Frustum] instance where plane0-plane6 define the left, right, bottom, top, far and near planes respectively.
/// See Camera.h and (filament) Frustum.h for more details.
///
Future<Frustum> getCameraFrustum();

View File

@@ -846,6 +846,14 @@ class FilamentControllerFFI extends FilamentController {
set_camera_focal_length(_viewer!, focalLength);
}
@override
Future setCameraCulling(double near, double far) async {
if (_viewer == null) {
throw Exception("No viewer available, ignoring");
}
set_camera_culling(_viewer!, near, far);
}
@override
Future setCameraFocusDistance(double focusDistance) async {
if (_viewer == null) {
@@ -1084,11 +1092,20 @@ class FilamentControllerFFI extends FilamentController {
_viewer!, mode.index, orbitSpeedX, orbitSpeedX, zoomSpeed);
}
///
/// I don't think these two methods are accurate - don't rely on them, use the Frustum values instead.
/// I think because we use [setLensProjection] and [setScaling] together, this projection matrix doesn't accurately reflect the field of view (because it's using an additional scaling matrix).
/// Also, the near/far planes never seem to get updated (which is what I would expect to see when calling [getCameraCullingProjectionMatrix])
///
@override
Future<Matrix4> getCameraProjectionMatrix() async {
if (_viewer == null) {
throw Exception("No viewer available");
}
print(
"WARNING: getCameraProjectionMatrix and getCameraCullingProjectionMatrix are not reliable. Consider these broken");
var arrayPtr = get_camera_projection_matrix(_viewer!);
var doubleList = arrayPtr.asTypedList(16);
var projectionMatrix = Matrix4.fromList(doubleList);
@@ -1101,6 +1118,8 @@ class FilamentControllerFFI extends FilamentController {
if (_viewer == null) {
throw Exception("No viewer available");
}
print(
"WARNING: getCameraProjectionMatrix and getCameraCullingProjectionMatrix are not reliable. Consider these broken");
var arrayPtr = get_camera_culling_projection_matrix(_viewer!);
var doubleList = arrayPtr.asTypedList(16);
var projectionMatrix = Matrix4.fromList(doubleList);
@@ -1113,9 +1132,27 @@ class FilamentControllerFFI extends FilamentController {
if (_viewer == null) {
throw Exception("No viewer available");
}
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)));
}
var projectionMatrix = await getCameraProjectionMatrix();
var frustum = Frustum();
frustum.plane0.setFromComponents(
doubleList[0], doubleList[1], doubleList[2], doubleList[3]);
frustum.plane1.setFromComponents(
doubleList[4], doubleList[5], doubleList[6], doubleList[7]);
frustum.plane2.setFromComponents(
doubleList[8], doubleList[9], doubleList[10], doubleList[11]);
frustum.plane3.setFromComponents(
doubleList[12], doubleList[13], doubleList[14], doubleList[15]);
frustum.plane4.setFromComponents(
doubleList[16], doubleList[17], doubleList[18], doubleList[19]);
frustum.plane5.setFromComponents(
doubleList[20], doubleList[21], doubleList[22], doubleList[23]);
return Frustum.matrix(projectionMatrix);
return frustum;
}
}

View File

@@ -629,6 +629,14 @@ external void set_camera_projection_matrix(
double far,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Double, ffi.Double)>(
symbol: 'set_camera_culling', assetId: 'flutter_filament_plugin')
external void set_camera_culling(
ffi.Pointer<ffi.Void> viewer,
double near,
double far,
);
@ffi.Native<ffi.Pointer<ffi.Double> Function(ffi.Pointer<ffi.Void>)>(
symbol: 'get_camera_culling_projection_matrix',
assetId: 'flutter_filament_plugin')