fix aspect

This commit is contained in:
Nick Fisher
2023-08-08 13:05:08 +08:00
parent 4ec9dbe756
commit 3e982e2993
4 changed files with 81 additions and 54 deletions

View File

@@ -188,6 +188,10 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
createDisplayLink() createDisplayLink()
result(self.flutterTextureId) result(self.flutterTextureId)
case "resize": case "resize":
if(viewer == nil) {
print("Error: cannot resize before a viewer has been created")
result(nil);
}
rendering = false rendering = false
destroy_swap_chain(viewer) destroy_swap_chain(viewer)
let args = call.arguments as! [Any] let args = call.arguments as! [Any]
@@ -196,6 +200,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
create_swap_chain(viewer, pixelBufferTextureId, UInt32(args[0] as! Int64), UInt32(args[1] as! Int64)) create_swap_chain(viewer, pixelBufferTextureId, UInt32(args[0] as! Int64), UInt32(args[1] as! Int64))
update_viewport_and_camera_projection(viewer, Int32(args[0] as! Int64), Int32(args[1] as! Int64), Float(args[2] as! Double)) update_viewport_and_camera_projection(viewer, Int32(args[0] as! Int64), Int32(args[1] as! Int64), Float(args[2] as! Double))
rendering = true rendering = true
print("Resized to \(args[0])x\(args[1])")
result(self.flutterTextureId); result(self.flutterTextureId);
case "createFilamentViewer": case "createFilamentViewer":
let callback = make_resource_loader(loadResource, freeResource, Unmanaged.passUnretained(self).toOpaque()) let callback = make_resource_loader(loadResource, freeResource, Unmanaged.passUnretained(self).toOpaque())
@@ -205,6 +210,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
viewer = create_filament_viewer(nil, callback) viewer = create_filament_viewer(nil, callback)
var pixelBufferTextureId = unsafeBitCast(pixelBuffer!, to: UnsafeRawPointer.self) var pixelBufferTextureId = unsafeBitCast(pixelBuffer!, to: UnsafeRawPointer.self)
create_swap_chain(viewer, pixelBufferTextureId, UInt32(width), UInt32(height)) create_swap_chain(viewer, pixelBufferTextureId, UInt32(width), UInt32(height))
update_viewport_and_camera_projection(viewer, Int32(args[0] as! Int64), Int32(args[1] as! Int64), 1.0)
result(unsafeBitCast(viewer, to:Int64.self)) result(unsafeBitCast(viewer, to:Int64.self))
case "deleteFilamentViewer": case "deleteFilamentViewer":
delete_filament_viewer(viewer) delete_filament_viewer(viewer)
@@ -545,10 +551,10 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
clear_assets(viewer) clear_assets(viewer)
result(true) result(true)
case "setCamera": case "setCamera":
guard let args = call.arguments as? [Any], args.count == 3, guard let args = call.arguments as? [Any], args.count == 2,
let asset = args[0] as? Int64, let asset = args[0] as? Int64,
let nodeName = args[1] as? String else { let nodeName = args[1] as? String else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "Expected viewer, asset, and nodeName for set_camera", details: nil)) result(FlutterError(code: "INVALID_ARGUMENTS", message: "Expected asset and nodeName for set_camera", details: nil))
return return
} }
let success = set_camera(viewer, Int32(asset), nodeName) let success = set_camera(viewer, Int32(asset), nodeName)

View File

@@ -830,10 +830,10 @@ void FilamentViewer::updateViewportAndCameraProjection(
const double aspect = (double)width / height; const double aspect = (double)width / height;
Camera& cam =_view->getCamera(); Camera& cam =_view->getCamera();
cam.setLensProjection(_cameraFocalLength, aspect, kNearPlane, cam.setLensProjection(_cameraFocalLength, 1.0f, kNearPlane,
kFarPlane); kFarPlane);
// cam.setScaling({1.0 / aspect, 1.0}); cam.setScaling({1.0 / aspect, 1.0});
Log("Set viewport to width: %d height: %d aspect %f scaleFactor : %f", width, height, aspect, Log("Set viewport to width: %d height: %d aspect %f scaleFactor : %f", width, height, aspect,
contentScaleFactor); contentScaleFactor);

View File

@@ -70,7 +70,6 @@ class FilamentController {
size = ui.Size(width * _pixelRatio, height * _pixelRatio); size = ui.Size(width * _pixelRatio, height * _pixelRatio);
_textureId = _textureId =
await _channel.invokeMethod("createTexture", [size.width, size.height]); await _channel.invokeMethod("createTexture", [size.width, size.height]);
_textureIdController.add(_textureId);
await _channel await _channel
.invokeMethod("createFilamentViewer", [size.width, size.height]); .invokeMethod("createFilamentViewer", [size.width, size.height]);
@@ -93,6 +92,7 @@ class FilamentController {
_initialized.complete(true); _initialized.complete(true);
_assetManager = await _channel.invokeMethod("getAssetManager"); _assetManager = await _channel.invokeMethod("getAssetManager");
_textureIdController.add(_textureId);
} }
Future resize(int width, int height, Future resize(int width, int height,

View File

@@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'dart:async'; import 'dart:async';
@@ -55,78 +56,98 @@ class FilamentWidget extends StatefulWidget {
} }
class _FilamentWidgetState extends State<FilamentWidget> { class _FilamentWidgetState extends State<FilamentWidget> {
StreamSubscription? _listener; StreamSubscription? _initializationListener;
StreamSubscription? _textureIdListener;
int? _textureId;
bool _resizing = false; bool _resizing = false;
bool _hasViewer = false;
@override @override
void initState() { void initState() {
_listener = widget.controller.onInitializationRequested.listen((_) { _initializationListener =
widget.controller.onInitializationRequested.listen((_) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
var size = ((context.findRenderObject()) as RenderBox).size; var size = ((context.findRenderObject()) as RenderBox).size;
print( print(
"Requesting creation of Filament back-end texture/viewer for viewport size $size"); "Requesting creation of Filament back-end texture/viewer for viewport size $size");
await widget.controller await widget.controller
.createViewer(size.width.toInt(), size.height.toInt()); .createViewer(size.width.toInt(), size.height.toInt());
print("Filament texture/viewer created."); setState(() {
_listener!.cancel(); _hasViewer = true;
_listener = null; });
_initializationListener!.cancel();
_initializationListener = null;
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
var size = ((context.findRenderObject()) as RenderBox).size;
widget.controller.resize(size.width.toInt(), size.height.toInt());
print("RESIZED IN POST FRAME CALLBACK TO $size");
});
setState(() {});
});
});
_textureIdListener = widget.controller.textureId.listen((int? textureId) {
setState(() {
_textureId = textureId;
}); });
setState(() {});
}); });
super.initState(); super.initState();
} }
@override
void dispose() { void dispose() {
_listener?.cancel(); _initializationListener?.cancel();
_textureIdListener?.cancel();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder( return LayoutBuilder(builder: ((context, constraints) {
stream: widget.controller.textureId, print("constraints $constraints");
builder: (ctx, AsyncSnapshot<int?> textureId) { if (_textureId == null) {
if (textureId.data == null) { return Container(color: Colors.transparent);
return Container(); }
}
var texture = Texture( var texture = Texture(
key: ObjectKey("texture_${textureId.data}"), key: ObjectKey("texture_$_textureId"),
textureId: textureId.data!, textureId: _textureId!,
filterQuality: FilterQuality.high, filterQuality: FilterQuality.high,
); );
return LayoutBuilder( return SizedBox(
builder: ((context, constraints) => SizedBox( height: constraints.maxHeight,
height: constraints.maxHeight, width: constraints.maxWidth,
width: constraints.maxWidth, child: ResizeObserver(
child: ResizeObserver( onResized: (Size oldSize, Size newSize) async {
onResized: (Size oldSize, Size newSize) async { if (!_hasViewer) {
WidgetsBinding.instance.addPostFrameCallback((_) async { return;
setState(() { }
_resizing = true; print("RESIZE OBSERVER $newSize");
}); WidgetsBinding.instance.addPostFrameCallback((_) async {
setState(() {
_resizing = true;
});
await widget.controller.resize( await widget.controller
newSize.width.toInt(), newSize.height.toInt()); .resize(newSize.width.toInt(), newSize.height.toInt());
WidgetsBinding.instance WidgetsBinding.instance.addPostFrameCallback((_) async {
.addPostFrameCallback((_) async { setState(() {
setState(() { _resizing = false;
_resizing = false; });
}); });
}); });
}); },
}, child: Platform.isLinux
child: Platform.isLinux ? _resizing
? _resizing ? Container()
? Container() : Transform(
: Transform( alignment: Alignment.center,
alignment: Alignment.center, transform: Matrix4.rotationX(
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?
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: texture)
child: texture) : texture));
: texture)))); }));
});
} }
} }