diff --git a/example/lib/main.dart b/example/lib/main.dart index f3e9b4e4..e85949e7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -55,6 +55,7 @@ class _ExampleWidgetState extends State { bool _initialized = false; bool _coneHidden = false; + bool _frustumCulling = true; @override void initState() { @@ -144,7 +145,10 @@ class _ExampleWidgetState extends State { }, 'transform to unit cube'), _item(() async { _filamentController.setPosition(_cube!, 1.0, 1.0, -1.0); - }, 'set position to 1, 1, -1'), + }, 'set cube position to 1, 1, -1'), + _item(() async { + _filamentController.setPosition(_cube!, 1.0, 1.0, -1.0); + }, 'move camera to cube position'), _item(() async { var frameData = Float32List.fromList( List.generate(120, (i) => i / 120).expand((x) { @@ -249,6 +253,18 @@ class _ExampleWidgetState extends State { _filamentController.setToneMapping(ToneMapper.LINEAR); }, "Set tone mapping to linear")); + children.add(_item(() { + _filamentController.moveCameraToAsset(_cube!); + }, "Move camera to asset")); + + children.add(_item(() { + setState(() { + _frustumCulling = !_frustumCulling; + }); + + _filamentController.setViewFrustumCulling(_frustumCulling); + }, "${_frustumCulling ? "Disable" : "Enable"} frustum culling")); + return Stack(children: [ Positioned( bottom: 100, diff --git a/ios/include/FilamentViewer.hpp b/ios/include/FilamentViewer.hpp index 8e12dcde..b849678a 100644 --- a/ios/include/FilamentViewer.hpp +++ b/ios/include/FilamentViewer.hpp @@ -86,6 +86,8 @@ namespace polyvox { void setBackgroundImage(const char* resourcePath, bool fillHeight); void clearBackgroundImage(); void setBackgroundImagePosition(float x, float y, bool clamp); + void moveCameraToAsset(EntityId entityId); + void setCameraExposure(float aperture, float shutterSpeed, float sensitivity); void setCameraPosition(float x, float y, float z); void setCameraRotation(float rads, float x, float y, float z); diff --git a/ios/include/PolyvoxFilamentApi.h b/ios/include/PolyvoxFilamentApi.h index 3a780269..319e4f4c 100644 --- a/ios/include/PolyvoxFilamentApi.h +++ b/ios/include/PolyvoxFilamentApi.h @@ -108,6 +108,7 @@ void transform_to_unit_cube(void* assetManager, EntityId asset); void set_position(void* assetManager, EntityId asset, float x, float y, float z); void set_rotation(void* assetManager, EntityId asset, float rads, float x, float y, float z); void set_scale(void* assetManager, EntityId asset, float scale); +void move_camera_to_asset(const void* const viewer, EntityId asset); void set_camera_exposure(const void* const viewer, float aperture, float shutterSpeed, float sensitivity); void set_camera_position(const void* const viewer, float x, float y, float z); void set_camera_rotation(const void* const viewer, float rads, float x, float y, float z); diff --git a/ios/src/AssetManager.cpp b/ios/src/AssetManager.cpp index 72caebf2..3272ca9e 100644 --- a/ios/src/AssetManager.cpp +++ b/ios/src/AssetManager.cpp @@ -21,6 +21,7 @@ #include "Log.hpp" #include "AssetManager.hpp" +#include "material/UnlitMaterialProvider.hpp" #include "material/FileMaterialProvider.hpp" // #include "gltfio/materials/uberarchive.h" diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 3b9eecf0..9ae687a9 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -908,9 +908,23 @@ void FilamentViewer::setCameraPosition(float x, float y, float z) { cam.setModelMatrix(_cameraPosition * _cameraRotation); } +void FilamentViewer::moveCameraToAsset(EntityId entityId) { + + auto asset = _assetManager->getAssetByEntityId(entityId); + if(!asset) { + Log("Failed to find asset attached to specified entity id."); + return; + } + + const filament::Aabb bb = asset->mAsset->getBoundingBox(); + Camera& cam =_view->getCamera(); + _cameraPosition = math::mat4f::translation(bb.getCorners()); + _cameraRotation = math::mat4f(); + cam.setModelMatrix(_cameraPosition * _cameraRotation); +} + void FilamentViewer::setCameraRotation(float rads, float x, float y, float z) { Camera& cam =_view->getCamera(); - _cameraRotation = math::mat4f::rotation(rads, math::float3(x,y,z)); cam.setModelMatrix(_cameraPosition * _cameraRotation); } diff --git a/ios/src/PolyvoxFilamentApi.cpp b/ios/src/PolyvoxFilamentApi.cpp index 59a4619a..516b5a26 100644 --- a/ios/src/PolyvoxFilamentApi.cpp +++ b/ios/src/PolyvoxFilamentApi.cpp @@ -96,6 +96,10 @@ extern "C" { return ((FilamentViewer*)viewer)->setCamera(asset, nodeName); } + void move_camera_to_asset(const void* const viewer, EntityId asset) { + ((FilamentViewer*)viewer)->moveCameraToAsset(asset, asset); + } + void set_camera_focus_distance(const void* const viewer, float distance) { ((FilamentViewer*)viewer)->setCameraFocusDistance(distance); } diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index f8543356..b236ecc9 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -4,6 +4,7 @@ import 'dart:ui' as ui; import 'package:flutter/services.dart'; import 'package:polyvox_filament/animations/bone_animation_data.dart'; import 'package:polyvox_filament/animations/morph_animation_data.dart'; +import 'package:polyvox_filament/generated_bindings_web.dart'; typedef AssetManager = int; typedef FilamentEntity = int; @@ -523,6 +524,20 @@ class FilamentController { await _channel.invokeMethod("setCameraPosition", [x, y, z]); } + Future moveCameraToAsset(FilamentEntity asset) async { + if (_viewer == null || _resizing) { + throw Exception("No viewer available, ignoring"); + } + await _channel.invokeMethod("moveCameraToAsset", asset); + } + + Future setViewFrustumCulling(bool enabled) async { + if (_viewer == null || _resizing) { + throw Exception("No viewer available, ignoring"); + } + await _channel.invokeMethod("setViewFrustumCulling", enabled); + } + Future setCameraExposure( double aperture, double shutterSpeed, double sensitivity) async { if (_viewer == null || _resizing) { diff --git a/lib/filament_gesture_detector.dart b/lib/filament_gesture_detector.dart index 6a8e644b..b872282a 100644 --- a/lib/filament_gesture_detector.dart +++ b/lib/filament_gesture_detector.dart @@ -13,13 +13,15 @@ class FilamentGestureDetector extends StatefulWidget { final FilamentController controller; final bool showControlOverlay; final bool enableControls; + final double zoomDelta; const FilamentGestureDetector( {Key? key, required this.controller, this.child, this.showControlOverlay = false, - this.enableControls = true}) + this.enableControls = true, + this.zoomDelta = 1}) : super(key: key); @override @@ -91,8 +93,9 @@ class _FilamentGestureDetectorState extends State { if (pointerSignal is PointerScrollEvent) { _scrollTimer?.cancel(); widget.controller.zoomBegin(); - widget.controller - .zoomUpdate(pointerSignal.scrollDelta.dy > 0 ? 1 : -1); + widget.controller.zoomUpdate(pointerSignal.scrollDelta.dy > 0 + ? widget.zoomDelta + : -widget.zoomDelta); _scrollTimer = Timer(Duration(milliseconds: 100), () { widget.controller.zoomEnd(); _scrollTimer = null; @@ -104,8 +107,11 @@ class _FilamentGestureDetectorState extends State { ? null : (d) async { if (d.buttons == kTertiaryButton || _rotating) { - widget.controller - .rotateStart(d.localPosition.dx, d.localPosition.dy); + print("Starting at ${d.position}"); + widget.controller.rotateStart( + d.position.dx * 2.0, + d.position.dy * + 2.0); // multiply by 2.0 to account for pixel density, TODO don't hardcode } else { widget.controller .panStart(d.localPosition.dx, d.localPosition.dy); @@ -116,7 +122,7 @@ class _FilamentGestureDetectorState extends State { : (PointerMoveEvent d) async { if (d.buttons == kTertiaryButton || _rotating) { widget.controller - .rotateUpdate(d.localPosition.dx, d.localPosition.dy); + .rotateUpdate(d.position.dx * 2.0, d.position.dy * 2.0); } else { widget.controller .panUpdate(d.localPosition.dx, d.localPosition.dy); diff --git a/lib/filament_widget.dart b/lib/filament_widget.dart index 15971ad3..ece6f4aa 100644 --- a/lib/filament_widget.dart +++ b/lib/filament_widget.dart @@ -155,7 +155,6 @@ class _FilamentWidgetState extends State { if (_textureId == null) { return widget.initial; } - var texture = Texture( key: ObjectKey("texture_$_textureId"), textureId: _textureId!, diff --git a/macos/Classes/SwiftPolyvoxFilamentPlugin.swift b/macos/Classes/SwiftPolyvoxFilamentPlugin.swift index e81166c1..9a8c9408 100644 --- a/macos/Classes/SwiftPolyvoxFilamentPlugin.swift +++ b/macos/Classes/SwiftPolyvoxFilamentPlugin.swift @@ -34,6 +34,8 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture var uriString = String(cString:uri!) var path:String? = nil + + print("Received request to load \(uriString)") if(uriString.hasPrefix("file://")) { path = String(uriString.dropFirst(7)) @@ -47,12 +49,13 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture if(path != nil) { do { - print("Attempting to load file at path \(path!)") + print("Loading file at path \(path!)") let data = try Data(contentsOf: URL(fileURLWithPath:path!)) let nsData = data as NSData let resId = UInt32(instance.resources.count) instance.resources[resId] = nsData let length = nsData.length + print("Got file of length \(length)") return ResourceBuffer(data:nsData.bytes, size:UInt32(nsData.count), id:UInt32(resId)) } catch { print("ERROR LOADING RESOURCE") @@ -613,7 +616,12 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture } let success = set_camera(viewer, asset, nodeName) result(success) - + case "moveCameraToAsset": + move_camera_to_asset(viewer, call.arguments as! EntityId) + result(true) + case "setViewFrustumCulling": + set_view_frustum_culling(viewer, call.arguments as! Bool) + result(true) case "setCameraPosition": let args = call.arguments as! [Any] set_camera_position(viewer, Float(args[0] as! Double), Float(args[1] as! Double), Float(args[2] as! Double)) diff --git a/macos/include/FilamentViewer.hpp b/macos/include/FilamentViewer.hpp index 10dd8633..99094b52 100644 --- a/macos/include/FilamentViewer.hpp +++ b/macos/include/FilamentViewer.hpp @@ -81,6 +81,8 @@ namespace polyvox { void setBackgroundImage(const char* resourcePath); void clearBackgroundImage(); void setBackgroundImagePosition(float x, float y, bool clamp); + void moveCameraToAsset(EntityId entityId); + void setViewFrustumCulling(bool enabled); void setCameraExposure(float aperture, float shutterSpeed, float sensitivity); void setCameraPosition(float x, float y, float z); void setCameraRotation(float rads, float x, float y, float z); diff --git a/macos/include/PolyvoxFilamentApi.h b/macos/include/PolyvoxFilamentApi.h index ec7d1f19..4ac543ae 100644 --- a/macos/include/PolyvoxFilamentApi.h +++ b/macos/include/PolyvoxFilamentApi.h @@ -89,6 +89,8 @@ void transform_to_unit_cube(void* assetManager, EntityId asset); void set_position(void* assetManager, EntityId asset, float x, float y, float z); void set_rotation(void* assetManager, EntityId asset, float rads, float x, float y, float z); void set_scale(void* assetManager, EntityId asset, float scale); +void move_camera_to_asset(const void* const viewer, EntityId asset); +void set_view_frustum_culling(const void* const viewer, bool enabled); void set_camera_exposure(const void* const viewer, float aperture, float shutterSpeed, float sensitivity); void set_camera_position(const void* const viewer, float x, float y, float z); void set_camera_rotation(const void* const viewer, float rads, float x, float y, float z); diff --git a/macos/src/AssetManager.cpp b/macos/src/AssetManager.cpp index 8e192d82..db37d2c9 100644 --- a/macos/src/AssetManager.cpp +++ b/macos/src/AssetManager.cpp @@ -51,19 +51,16 @@ _scene(scene) { _gltfResourceLoader = new ResourceLoader({.engine = _engine, .normalizeSkinningWeights = true }); -sdfsdfds auto uberdata = resourceLoaderWrapper->load("packages/polyvox_filament/assets/default.uberz"); _ubershaderProvider = gltfio::createUbershaderProvider( - _engine, uberdata.data, uberdata.size); + _engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE); + + // _ubershaderProvider = gltfio::createJitShaderProvider(_engine, true); // _ubershaderProvider = new StandardMaterialProvider(_engine); EntityManager &em = EntityManager::get(); - - //_unlitProvider = new UnlitMaterialProvider(_engine); - - // auto rb = _resourceLoaderWrapper->load("file:///mnt/hdd_2tb/home/hydroxide/projects/polyvox/flutter/polyvox_filament/materials/toon.filamat"); - // auto toonProvider = new FileMaterialProvider(_engine, rb.data, (size_t) rb.size); + _assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em }); _gltfResourceLoader->addTextureProvider("image/ktx2", _ktxDecoder); @@ -74,7 +71,6 @@ sdfsdfds AssetManager::~AssetManager() { _gltfResourceLoader->asyncCancelLoad(); _ubershaderProvider->destroyMaterials(); - //_unlitProvider->destroyMaterials(); destroyAll(); AssetLoader::destroy(&_assetLoader); diff --git a/macos/src/FilamentViewer.cpp b/macos/src/FilamentViewer.cpp index f4c03d7e..8e8b826e 100644 --- a/macos/src/FilamentViewer.cpp +++ b/macos/src/FilamentViewer.cpp @@ -861,6 +861,27 @@ void FilamentViewer::updateViewportAndCameraProjection( contentScaleFactor); } +void FilamentViewer::moveCameraToAsset(EntityId entityId) { + + auto asset = _assetManager->getAssetByEntityId(entityId); + if(!asset) { + Log("Failed to find asset attached to specified entity id."); + return; + } + + const filament::Aabb bb = asset->getBoundingBox(); + auto corners = bb.getCorners(); + Camera& cam =_view->getCamera(); + auto eye = corners.vertices[0] * 1.5; + auto lookAt = corners.vertices[7]; + cam.lookAt(eye, lookAt); + Log("Moved camera to %f %f %f, lookAt %f %f %f, near %f far %f", eye[0], eye[1], eye[2], lookAt[0], lookAt[1], lookAt[2], cam.getNear(), cam.getCullingFar()); +} + +void FilamentViewer::setViewFrustumCulling(bool enabled) { + _view->setFrustumCullingEnabled(enabled); +} + void FilamentViewer::setCameraPosition(float x, float y, float z) { Camera& cam =_view->getCamera(); @@ -915,7 +936,7 @@ void FilamentViewer::grabUpdate(float x, float y) { return; } Camera& cam =_view->getCamera(); - auto eye = cam.getPosition();// math::float3 {0.0f, 0.5f, 50.0f } ;// ; // + auto eye = cam.getPosition(); auto target = eye + cam.getForwardVector(); auto upward = cam.getUpVector(); Viewport const& vp = _view->getViewport(); @@ -924,9 +945,7 @@ void FilamentViewer::grabUpdate(float x, float y) { cam.setModelMatrix(trans); } else { auto trans = cam.getModelMatrix() * mat4::rotation( - - 0.01, -// math::float3 { 0.0f, 1.0f, 0.0f }); + 0.02, math::float3 { (y - _startY) / vp.height, (x - _startX) / vp.width, 0.0f }); cam.setModelMatrix(trans); } diff --git a/macos/src/PolyvoxFilamentApi.cpp b/macos/src/PolyvoxFilamentApi.cpp index 64e7cffc..8b657d6d 100644 --- a/macos/src/PolyvoxFilamentApi.cpp +++ b/macos/src/PolyvoxFilamentApi.cpp @@ -97,6 +97,14 @@ extern "C" { return ((FilamentViewer*)viewer)->setCamera(asset, nodeName); } + FLUTTER_PLUGIN_EXPORT void move_camera_to_asset(const void* const viewer, EntityId asset) { + ((FilamentViewer*)viewer)->moveCameraToAsset(asset); + } + + FLUTTER_PLUGIN_EXPORT void set_view_frustum_culling(const void* const viewer, bool enabled) { + ((FilamentViewer*)viewer)->setViewFrustumCulling(enabled); + } + FLUTTER_PLUGIN_EXPORT void set_camera_focus_distance(const void* const viewer, float distance) { ((FilamentViewer*)viewer)->setCameraFocusDistance(distance); }