add setter for frame interval, separate FilamentController initialization from widget

This commit is contained in:
Nick Fisher
2022-09-01 14:26:31 +10:00
parent f68fea29d8
commit dc9e639c40
8 changed files with 134 additions and 33 deletions

View File

@@ -149,12 +149,12 @@ FilamentViewer::FilamentViewer(void *layer, LoadResource loadResource,
Log("Engine created"); Log("Engine created");
_renderer = _engine->createRenderer(); _renderer = _engine->createRenderer();
float fr = 60.0f;
_renderer->setDisplayInfo({.refreshRate = 60.0f, _renderer->setDisplayInfo({.refreshRate = fr,
.presentationDeadlineNanos = (uint64_t)0, .presentationDeadlineNanos = (uint64_t)0,
.vsyncOffsetNanos = (uint64_t)0}); .vsyncOffsetNanos = (uint64_t)0});
Renderer::FrameRateOptions fro; Renderer::FrameRateOptions fro;
fro.interval = 60; fro.interval = 1 / fr;
_renderer->setFrameRateOptions(fro); _renderer->setFrameRateOptions(fro);
_scene = _engine->createScene(); _scene = _engine->createScene();
@@ -247,6 +247,13 @@ static constexpr float4 sFullScreenTriangleVertices[3] = {
static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2}; static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2};
void FilamentViewer::setFrameInterval(float frameInterval) {
Renderer::FrameRateOptions fro;
fro.interval = frameInterval;
_renderer->setFrameRateOptions(fro);
Log("Set framerate interval to %f", frameInterval);
}
void FilamentViewer::createImageRenderable() { void FilamentViewer::createImageRenderable() {
if (_imageEntity) if (_imageEntity)
@@ -618,7 +625,7 @@ void FilamentViewer::loadIbl(const char *const iblPath) {
} }
} }
void FilamentViewer::render() { void FilamentViewer::render(uint64_t frameTimeInNanos) {
if (!_view || !_mainCamera || !_swapChain) { if (!_view || !_mainCamera || !_swapChain) {
Log("Not ready for rendering"); Log("Not ready for rendering");
@@ -637,7 +644,7 @@ void FilamentViewer::render() {
} }
// Render the scene, unless the renderer wants to skip the frame. // Render the scene, unless the renderer wants to skip the frame.
if (_renderer->beginFrame(_swapChain)) { if (_renderer->beginFrame(_swapChain, frameTimeInNanos)) {
_renderer->render(_view); _renderer->render(_view);
_renderer->endFrame(); _renderer->endFrame();
} }

View File

@@ -61,7 +61,8 @@ namespace polyvox {
void clearAssets(); void clearAssets();
void updateViewportAndCameraProjection(int height, int width, float scaleFactor); void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
void render(); void render(uint64_t frameTimeInNanos);
void setFrameInterval(float interval);
bool setFirstCamera(SceneAsset* asset); bool setFirstCamera(SceneAsset* asset);
bool setCamera(SceneAsset* asset, const char* nodeName); bool setCamera(SceneAsset* asset, const char* nodeName);

View File

@@ -69,9 +69,17 @@ extern "C" {
} }
void render( void render(
void* viewer void* viewer,
uint64_t frameTimeInNanos
) { ) {
((FilamentViewer*)viewer)->render(); ((FilamentViewer*)viewer)->render(frameTimeInNanos);
}
void set_frame_interval(
void* viewer,
float frameInterval
) {
((FilamentViewer*)viewer)->setFrameInterval(frameInterval);
} }
void destroy_swap_chain(void* viewer) { void destroy_swap_chain(void* viewer) {

View File

@@ -16,8 +16,9 @@ void remove_ibl(void* viewer);
void* load_glb(void* viewer, const char* assetPath); void* load_glb(void* viewer, const char* assetPath);
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath); void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
bool set_camera(void* viewer, void* asset, const char* nodeName); bool set_camera(void* viewer, void* asset, const char* nodeName);
void render(void* viewer); void render(void* viewer, uint64_t frameTimeInNanos);
void destroy_swap_chain(void* viewer); void destroy_swap_chain(void* viewer);
void set_frame_interval(void* viewer, float interval);
void* get_renderer(void* viewer); void* get_renderer(void* viewer);
void update_viewport_and_camera_projection(void* viewer, int width, int height, float scaleFactor); void update_viewport_and_camera_projection(void* viewer, int width, int height, float scaleFactor);

View File

@@ -7,7 +7,10 @@ typedef FilamentAsset = int;
abstract class FilamentController { abstract class FilamentController {
late int textureId; late int textureId;
Future get initialized; Future get initialized;
Future initialize(int width, int height, { double devicePixelRatio = 1}); Stream get onInitializationRequested;
Future initialize();
Future createTextureViewer(int width, int height, { double devicePixelRatio = 1});
Future setFrameRate(int framerate);
Future resize(int width, int height, { double devicePixelRatio = 1, double contentScaleFactor=1}); Future resize(int width, int height, { double devicePixelRatio = 1, double contentScaleFactor=1});
Future setBackgroundImage(String path); Future setBackgroundImage(String path);
Future loadSkybox(String skyboxPath); Future loadSkybox(String skyboxPath);
@@ -64,6 +67,10 @@ class PolyvoxFilamentController extends FilamentController {
late MethodChannel _channel = MethodChannel("app.polyvox.filament/event"); late MethodChannel _channel = MethodChannel("app.polyvox.filament/event");
late double _devicePixelRatio; late double _devicePixelRatio;
final _onInitRequestedController = StreamController();
Stream get onInitializationRequested => _onInitRequestedController.stream;
final _initialized = Completer(); final _initialized = Completer();
Future get initialized => _initialized.future; Future get initialized => _initialized.future;
@@ -74,7 +81,16 @@ class PolyvoxFilamentController extends FilamentController {
}); });
} }
Future initialize(int width, int height, { double devicePixelRatio=1 }) async { Future initialize() async {
_onInitRequestedController.add(true);
return _initialized.future;
}
Future setFrameRate(int framerate) async {
await _channel.invokeMethod("setFrameInterval", 1/ framerate);
}
Future createTextureViewer(int width, int height, { double devicePixelRatio=1 }) async {
_devicePixelRatio = devicePixelRatio; _devicePixelRatio = devicePixelRatio;
textureId = await _channel.invokeMethod("initialize", [width*devicePixelRatio, height*devicePixelRatio]); textureId = await _channel.invokeMethod("initialize", [width*devicePixelRatio, height*devicePixelRatio]);
_initialized.complete(true); _initialized.complete(true);

View File

@@ -55,16 +55,19 @@ class _FilamentWidgetState extends State<FilamentWidget> {
@override @override
void initState() { void initState() {
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("Requesting texture creation for Filament of size $size"); print("Requesting texture creation for Filament of size $size");
await widget.controller await widget.controller
.initialize(size.width.toInt(), size.height.toInt()); .createTextureViewer(size.width.toInt(), size.height.toInt());
print("Filament texture available"); print("Filament texture available");
setState(() { setState(() {
_ready = true; _ready = true;
}); });
}); });
});
super.initState(); super.initState();
} }

View File

@@ -95,7 +95,9 @@ class _GestureDetectingFilamentViewState
}, },
child: FilamentWidget(controller: widget.controller))), child: FilamentWidget(controller: widget.controller))),
widget.showControls widget.showControls
? Align(alignment:Alignment.bottomRight, child:GestureDetector( ? Align(
alignment: Alignment.bottomRight,
child: GestureDetector(
onTap: () { onTap: () {
setState(() { setState(() {
_rotate = !_rotate; _rotate = !_rotate;

View File

@@ -0,0 +1,63 @@
// import 'package:flutter/widgets.dart';
// import 'package:polyvox_filament/filament_controller.dart';
// import 'package:polyvox_filament/filament_controller.dart';
// import 'package:vector_math/vector_math_64.dart';
// class Position {
// final double x;
// final double y;
// final double z;
// Position(this.x, this.y, this.z);
// Position copy({double? x, double? y, double? z}) {
// return Position(x ?? this.x, y ?? this.y, z ?? this.z);
// }
// factory Position.zero() {
// return Position(0,0,0);
// }
// }
// class Rotation {
// final double rads;
// final double x;
// final double y;
// final double z;
// Rotation(this.x, this.y, this.z, this.rads);
// Rotation copy({double? rads, double? x, double? y, double? z}) {
// return Rotation(x ?? this.x, y ?? this.y, z ?? this.z, rads ?? this.rads);
// }
// factory Rotation.zero() {
// return Rotation(0, 1,0,0);
// }
// }
// ///
// /// Handles local transforms for assets/cameras.
// ///
// class TransformManager {
// final FilamentController _controller;
// Matrix4 transform = Matrix4.identity();
// TransformManager(this._controller);
// void scale(double scale) {
// transform.scale(scale, scale, scale);
// }
// void translate(double x, double y, double z) {
// transform.translate(x,y,z);
// }
// void rotate(double x, double y, double z) {
// transform.rotate(Vector3(x,y,z));
// }
// }