Compare commits

...

136 Commits

Author SHA1 Message Date
Nick Fisher
76f723c497 Makefile/README updates 2023-11-09 12:24:22 +08:00
Nick Fisher
a1f2b245ff move Makefile to macos folder and update instructions 2023-11-09 12:12:04 +08:00
Daverin
672952f8a0 cherry-pick a0671a9b6f084ee02f1f5b7000e34f884fd27241
cherry-pick a0671a9b6f084ee02f1f5b7000e34f884fd27241
2023-11-09 12:04:24 +08:00
Nick Fisher
395de95d37 more methods for projection/culling projection matrices & frustum 2023-11-09 11:41:40 +08:00
Nick Fisher
e1141098d0 example project fixes 2023-11-09 11:22:56 +08:00
Nick Fisher
2db353cc3b add getCameraFrustum() and getCameraProjectionMatrix() 2023-11-08 20:30:14 +08:00
Nick Fisher
962d53442f update macOS 2023-11-08 17:47:21 +08:00
Nick Fisher
af543f46b2 add onLoad/onUnload streams 2023-11-08 17:47:11 +08:00
Nick Fisher
7b0dcf2c1c update integration test 2023-11-08 17:46:23 +08:00
Nick Fisher
e15722b15b fix Android example project 2023-11-07 15:12:36 +08:00
Nick Fisher
0748323316 add free() method for stability on Windows 2023-11-07 17:54:57 +11:00
Nick Fisher
e42d5e6263 correctly initialize manipulatorMode to default 2023-11-07 17:49:21 +11:00
Nick Fisher
a2543aa69d fix hasViewer check in example ControllerMenu 2023-11-07 17:26:15 +11:00
Nick Fisher
921f654978 update generated_bindings with consistent assetId flutter_filament_plugin 2023-11-07 17:25:36 +11:00
Nick Fisher
914b2fad94 remove old web build folder 2023-11-07 16:58:20 +11:00
Nick Fisher
03fe1a097b update pubspec.lock 2023-11-07 13:15:27 +08:00
Nick Fisher
b5fffe617e use ffi-native for generated bindings 2023-11-07 13:15:12 +08:00
Nick Fisher
60ed8443b2 example project fixes 2023-11-07 13:14:46 +08:00
Nick Fisher
2882f9739d Merge pull request #13 from odd-io/feature-code-quality
Refactored /lib code to reduce analyze warnings
2023-11-07 08:42:49 +08:00
Nick Fisher
59936c6220 Merge pull request #12 from odd-io/feature-add-github-actions
Add GitHub Actions workflows
2023-11-07 08:41:11 +08:00
LukasPoque
509a480603 add GitHub Actions workflows for Dart Analyzer and
PubDev Score calculation
2023-11-06 17:35:31 +01:00
LukasPoque
93693788ac fix dart docs to match the method args naming 2023-11-06 17:19:40 +01:00
LukasPoque
793bc6ca32 Refactor gesture type enum to use camelCase 2023-11-06 17:13:25 +01:00
LukasPoque
9862f39bcd fix lint warnings through ignore lines 2023-11-06 17:13:13 +01:00
LukasPoque
1c55526463 Refactor FilamentControllerFFI class to use entity
instead of asset  to match overridden method
2023-11-06 17:12:03 +01:00
LukasPoque
229357d8b9 Change print to log to follow bp 2023-11-06 16:55:52 +01:00
LukasPoque
94680c6db7 Fix typos and comments in FilamentControllerFFI
and AnimationBuilder classes
2023-11-06 16:41:07 +01:00
LukasPoque
851d2df84e Run dart fix in lib 2023-11-06 14:27:16 +01:00
Nick Fisher
8120cbea6d properly free memory in model/view matrix getters 2023-11-03 22:43:04 +08:00
Nick Fisher
48be185bba start using menu for example project & add methods for getting camera model/view matrices 2023-11-03 22:17:39 +08:00
Nick Fisher
f5cc7a8174 update example project 2023-11-03 17:28:25 +08:00
Nick Fisher
58a9542121 add model/view matrix getters & manipulator options 2023-11-03 15:20:15 +08:00
Nick Fisher
83469e93b9 add new interface methods for camera 2023-11-03 13:18:04 +08:00
Nick Fisher
7700ead724 remove delay on resume 2023-11-03 13:10:22 +08:00
Nick Fisher
5ba5d7d6ea add mutex for animation updates 2023-11-03 13:10:02 +08:00
Nick Fisher
6671ced45d add delay to setRendering when coming back from inactive 2023-11-02 22:05:57 +08:00
Nick Fisher
a366867d91 correctly complete completer when resizing while unmounted and log any errors on resize 2023-11-01 14:05:49 +08:00
Nick Fisher
214510b595 remove wasm_ffi dependency 2023-11-01 13:47:25 +08:00
Nick Fisher
aa6ad3cc4b fix integration test 2023-10-28 15:21:04 +08:00
Nick Fisher
23364ba9a2 Merge branch 'develop' of github.com:nmfisher/polyvox_filament into develop 2023-10-28 15:17:32 +08:00
Nick Fisher
78094fbf61 update example project 2023-10-27 20:58:33 +08:00
Nick Fisher
4280172767 remove old Method Channel FilamentController 2023-10-27 20:57:33 +08:00
Nick Fisher
4a5c62a306 move rect ValueNotifier to interface 2023-10-27 20:57:13 +08:00
Nick Fisher
40485081bc require createViewer to be specified manually 2023-10-27 20:32:16 +08:00
Nick Fisher
42c0d96e56 add buster to example project 2023-10-27 00:19:17 +11:00
Nick Fisher
59c2f8d125 add ARCHITECTURE.md 2023-10-26 11:38:25 +08:00
Nick Fisher
cf25d8f0d7 update macOS 2023-10-26 11:12:31 +08:00
Nick Fisher
8b9e6a2b3a rename plugin from PolyvoxFilament to FlutterFilament
rename plugin from PolyvoxFilament to FlutterFilament
2023-10-26 14:08:20 +11:00
Nick Fisher
b42d31a773 fix window minimization issue on Windows 2023-10-26 12:49:24 +11:00
Nick Fisher
53c908dd0d use short timeout on front-end for resizing on Windows 2023-10-26 12:38:52 +11:00
Nick Fisher
6399ca41ed use pixelRatio properly 2023-10-26 11:33:44 +11:00
Nick Fisher
a56943fb86 use pixelRatio properly 2023-10-26 11:27:42 +11:00
Nick Fisher
38b58b6d8f set pixel ratio in FilamentWidget 2023-10-26 11:19:35 +11:00
Nick Fisher
0fdbf0b5be don't hide backing window when resizing 2023-10-26 02:14:55 +11:00
Nick Fisher
2fd6f44785 fixes for window resizing on Windows 2023-10-26 02:10:22 +11:00
Nick Fisher
0928d9d273 rendering correctly with backing window but some issues re pixel density, scroll & foregrounding on start 2023-10-25 17:52:37 +11:00
Nick Fisher
8cea106b30 refactor Windows classes to separate EGL/WGL/Backing Window 2023-10-25 13:11:58 +11:00
Nick Fisher
c4245b0dd3 remove duplicate EGL_ALPHA_SIZE on Windows 2023-10-24 13:23:41 +11:00
Nick Fisher
2107a17219 update pubspec.lock 2023-10-24 12:29:00 +11:00
Nick Fisher
e39d75824e update Windows example project 2023-10-24 12:29:00 +11:00
Nick Fisher
3f988a119c FlutterAngleTexture invoke resize callback on size change, cleanup on destruction and call glFinish in RenderCallback
FlutterAngleTexture invoke resize callback on size change, cleanup on destruction and call glFinish in RenderCallback
move OpenGlTextureBuffer cleanup to destructor
2023-10-24 12:28:57 +11:00
Nick Fisher
435ed7bee6 don't use resize callback on Windows and use ListenableBuilder for texture ID changes
don't use resize callback on Windows and use ListenableBuilder for texture ID changes
2023-10-24 12:28:54 +11:00
Nick Fisher
537f0e1c8e change TextureDetails to ValueNotifier and add MethodChannel listener on Dart side for resize (Windows only) 2023-10-24 12:23:20 +11:00
Nick Fisher
65426aa075 update README 2023-10-24 12:21:33 +11:00
Nick Fisher
7c554e871f update Windows ANGLE libs 2023-10-24 12:21:11 +11:00
Nick Fisher
72c1cbdeb3 remove custom platform creation from FlutterAngleTexture 2023-10-23 01:36:20 +11:00
Nick Fisher
69a7a07ec7 remove custom platform creation from FlutterAngleTexture 2023-10-23 01:36:03 +11:00
Nick Fisher
0a612555b8 remove custom platform creation from FlutterAngleTexture 2023-10-23 01:35:45 +11:00
Nick Fisher
600905f7f2 remove custom platform creation 2023-10-23 01:35:21 +11:00
Nick Fisher
73db953564 don't show placeholder while resizing 2023-10-23 01:34:48 +11:00
Nick Fisher
8130319801 don't null out controller textureDetails while resizing 2023-10-23 01:34:20 +11:00
Nick Fisher
34542a29ca add flushAndWait call to destroySwapChain 2023-10-23 01:33:47 +11:00
Nick Fisher
d15aa66f78 remove unnecessary bluegl from Windows/ANGLE build 2023-10-22 17:46:09 +11:00
Nick Fisher
1e6f9dcc9d initialize various FilamentViewer pointers to nullptr 2023-10-22 17:45:48 +11:00
Nick Fisher
74cfe8d9a1 store driver when creating texture 2023-10-22 17:45:26 +11:00
Nick Fisher
2b9ddef5e7 use shared EGLContext for ANGLE on Windows 2023-10-22 17:45:09 +11:00
Nick Fisher
991e09df32 update gitattributes 2023-10-19 16:40:09 +08:00
Nick Fisher
2910c34ae5 update macos/Android GLES uberz 2023-10-19 16:39:50 +08:00
Nick Fisher
67c8e503b3 update README 2023-10-19 16:37:23 +08:00
Nick Fisher
ed3555c237 reorder morph animations according to actual mesh morph targets 2023-10-18 16:04:14 +08:00
Nick Fisher
50c47fe908 move LiveLinkFace-related data loaders to viewer project 2023-10-18 14:37:45 +08:00
Nick Fisher
721726d2d5 update macOS 2023-10-18 13:48:03 +08:00
Nick Fisher
b26500af20 change default value for wasRenderingOnInactive to true 2023-10-18 13:47:11 +08:00
Nick Fisher
482ab29f49 iterate over completed animations in reverse order 2023-10-18 10:40:56 +08:00
Nick Fisher
7ff6f6eaf7 don't resize on resume 2023-10-17 22:12:39 +08:00
Nick Fisher
73b2633f4d add permissions check to example project
add permission check to example project

add permission check to example project
2023-10-17 18:25:42 +08:00
Nick Fisher
7f7eb89a45 remove debug mode delay on Android 2023-10-17 18:25:41 +08:00
Nick Fisher
3640e27324 remove superseded resize method call handler
remove superseded resize method call handler
2023-10-17 18:25:38 +08:00
Nick Fisher
53b8d352da Merge branch 'develop' of github.com:nmfisher/polyvox_filament into develop 2023-10-17 08:57:49 +08:00
Nick Fisher
2553d854e9 replace isReadyForScene with hasViewer stream and update version number/CHANGELOG 2023-10-17 08:57:00 +08:00
Nick Fisher
7f9c5a0f2d (re)set rendering on all lifecycle changes 2023-10-17 08:55:49 +08:00
Nick Fisher
7718885781 update README 2023-10-17 00:55:51 +11:00
Nick Fisher
5bf21ceaf9 update README 2023-10-17 00:54:19 +11:00
Nick Fisher
d3f84f156a update README 2023-10-16 21:46:21 +08:00
Nick Fisher
4fe79e3b92 remove golden_toolkit from test dependency 2023-10-17 00:29:21 +11:00
Nick Fisher
2a5c863506 remove golden_toolkit from test dependency 2023-10-17 00:26:11 +11:00
Nick Fisher
837a2cebc7 different timeouts for resize in debug/release 2023-10-17 00:25:30 +11:00
Nick Fisher
6ab814114e rewrite resize handler for better support on Windows 2023-10-17 00:13:44 +11:00
Nick Fisher
818d75b493 specify minimum Flutter version in README 2023-10-16 18:24:45 +11:00
Nick Fisher
390b3d063b don't use postFrameCallback in FilamentWidget resize 2023-10-16 15:08:23 +08:00
Nick Fisher
a0cdbde89f minor cleanup 2023-10-16 15:07:57 +08:00
Nick Fisher
4088853705 update gitattributes 2023-10-16 15:06:40 +08:00
Nick Fisher
b46cf85c83 delete old goldens on regenerate 2023-10-16 15:06:29 +08:00
Nick Fisher
e71f89e54f update integration tests + goldens 2023-10-16 15:06:10 +08:00
Nick Fisher
91d3894c83 make ResourceBuffer rvalue ref constructor noexcept 2023-10-16 17:02:59 +11:00
Nick Fisher
6cf8e58bed refactor resizing to address race condition on Windows 2023-10-16 17:02:24 +11:00
Nick Fisher
025bdf662e update windows libs 2023-10-16 17:00:06 +11:00
Nick Fisher
4ebd5a6645 wip 2023-10-13 17:22:31 +11:00
Nick Fisher
df4f647333 add DestroyTexture for pixelBuffer implementation 2023-10-13 16:53:39 +11:00
Nick Fisher
b089ddd501 Merge branch 'develop' of github.com:nmfisher/polyvox_filament into develop 2023-10-13 12:57:44 +08:00
Nick Fisher
57cff7fa47 update README re dead strip on iOS 2023-10-13 12:57:30 +08:00
Nick Fisher
450aacf0cc add dummy destroyTexture method on Windows 2023-10-13 12:56:06 +08:00
Nick Fisher
1a71e199aa add x64 to excluded architectures 2023-10-13 12:55:47 +08:00
Nick Fisher
91e50cf0ef update macOS sources 2023-10-13 12:55:32 +08:00
Nick Fisher
0276c29d10 update MacOS release project to only build active architecture in release 2023-10-13 12:55:14 +08:00
Nick Fisher
64309eeb54 make FilamentWidget const and display error on createViewer throwing exception 2023-10-13 12:54:58 +08:00
Nick Fisher
504cc8ca30 add option for resize to example project 2023-10-13 12:54:33 +08:00
Nick Fisher
28e26a722f don't strip symbols in release project 2023-10-13 12:53:50 +08:00
Nick Fisher
18274ab14d add resize to integration test 2023-10-13 12:53:28 +08:00
Nick Fisher
1fe130d77f Update README.md 2023-10-13 12:50:44 +08:00
Nick Fisher
eada8d23bd update README 2023-10-13 12:49:03 +08:00
Nick Fisher
7f107708b5 fix resizing 2023-10-13 11:24:29 +08:00
Nick Fisher
72ec72660d fix cancelling resize timer 2023-10-13 11:24:05 +08:00
Nick Fisher
6bddc94b3d regenerate FFI bindings 2023-10-13 11:23:13 +08:00
Nick Fisher
4eebe02f29 add destroy_swap_chain_ffi and move setRendering into its own task 2023-10-13 11:22:42 +08:00
Nick Fisher
6327c8063b fix missing return values on platform channels for destroyTexture 2023-10-13 11:22:08 +08:00
Nick Fisher
05bc5b122e update README 2023-10-13 10:15:07 +08:00
Nick Fisher
d655672587 more documentation for FilamentController 2023-10-13 10:14:43 +08:00
Nick Fisher
8358c0b236 add integration tests and update README 2023-10-12 21:48:44 +08:00
Nick Fisher
80388c059d README updates 2023-10-11 15:37:41 +08:00
Nick Fisher
3b2d87536a update README 2023-10-11 15:36:08 +08:00
Nick Fisher
1be2367b4f don't expose FILAMENT_ASSET_ERROR 2023-10-11 15:34:19 +08:00
Nick Fisher
08ba9400d3 whitespace 2023-10-11 15:32:03 +08:00
Nick Fisher
4d827badc4 add abstract def for getNameForEntity 2023-10-11 15:31:47 +08:00
Nick Fisher
e3408625bc gesture updates for mobile 2023-10-11 15:09:32 +08:00
Nick Fisher
78af8e12a0 add infinite loop check for pick_ffi 2023-10-11 15:00:17 +08:00
477 changed files with 7901 additions and 91042 deletions

607
.gitattributes vendored
View File

@@ -1,597 +1,12 @@
linux/lib/**/* filter=lfs diff=lfs merge=lfs -text
linux/lib/libspirv-cross-msl.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbenchmark.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbluevk.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilagui.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libgltf-demo-resources.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libsuzanne-resources.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libzstd.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libpng.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbluegl.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libgeometry.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libktxreader.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilament.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libglslang.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmathio.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libOSDependent.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libdracodec.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libsdl2.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilamat_combined.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libimage.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libsample-resources.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV-Tools-link.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libstb.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libimageio.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libutils.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libassimp.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libgtest.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libshaders.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV-Tools-lint.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbasis_encoder.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilamat.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmath.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV-Tools-reduce.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libviewer.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilamentapp.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libibl.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libOGLCompiler.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libspirv-cross-core.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV-Tools-diff.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbenchmark_main.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libcamutils.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilamentapp-resources.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libgetopt.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libspirv-cross-glsl.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libbackend.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libimgui.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmatdbg_resources.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmatlang.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmatdbg_combined.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV-Tools.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libgltfio.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libz.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libmatdbg.a filter=lfs diff=lfs merge=lfs -text
linux/lib/libSPIRV-Tools-opt.a filter=lfs diff=lfs merge=lfs -text
windows/lib/** filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/MaterialEnums.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/materials/uberarchive.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/scalar.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/AcquiredImage.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/Platform.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/compiler.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/uberz/ArchiveEnums.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/uberz/WritableArchive.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Texture.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/SkinningBuffer.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/quat.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/bitset.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament-iblprefilter/IBLPrefilterContext.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libimage.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/PresentCallable.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/camutils/compiler.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/mathio/ostream.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/EntityManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/viewer/RemoteServer.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libgeometry.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/Program.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformEGL.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Exposure.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/materials filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/geometry/SurfaceOrientation.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/TQuatHelpers.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/OpenGLPlatform.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/ColorSpace.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/RenderTarget.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/viewer/AutomationSpec.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libktxreader.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformCocoaTouchGL.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Scene.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/compressed_pair.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/viewer/AutomationEngine.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/fast.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/half.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilamat.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/README.md filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament-iblprefilter filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Color.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ktxreader/Ktx1Reader.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/camutils/Manipulator.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/geometry/Transcoder.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libgeometry.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Panic.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/viewer/Settings.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilament.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Stream.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Viewport.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/FilamentInstance.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/NameComponentManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filamat/Package.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/TextureSampler.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/mat2.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/View.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/tsl/robin_growth_policy.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libviewer.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Material.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Allocator.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/VertexBuffer.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/TVecHelpers.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libibl.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libbackend.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/ColorGrading.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Fence.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/AssetLoader.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/SpinLock.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libshaders.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformGLX.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filamat filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libzstd.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/README.md filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/RenderableManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Skybox.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/memalign.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filameshio/MeshReader.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/PrivateImplementation.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/generic/Mutex.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformEGLHeadless.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/DebugRegistry.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/tsl/robin_set.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/Handle.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl/CubemapIBL.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/VulkanPlatform.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/FilamentEntity.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/LICENSE filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/BufferDescriptor.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilament.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ktxreader filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Entity.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Slice.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/algorithm.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/SamplerDescriptor.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/LightManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/ToneMapper.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl filter=lfs diff=lfs merge=lfs -text
ios/lib/libdracodec.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/DriverEnums.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/SingleInstanceComponentManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Engine.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/TextureProvider.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/tsl filter=lfs diff=lfs merge=lfs -text
ios/lib/libviewer.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/TargetBufferInfo.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/mathfwd.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/vec2.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/IndexBuffer.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/image/ImageOps.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/uberz/ReadableArchive.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/CallStack.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Box.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Camera.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/mat4.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/SwapChain.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl/CubemapSH.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/BitmaskEnum.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/PrivateImplementation-impl.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/TransformManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/NodeManager.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/TMatHelpers.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/PipelineState.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/camutils filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/FilamentAPI.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Renderer.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libshaders.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filameshio filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl/utilities.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/vec3.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libcamutils.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filamat/MaterialBuilder.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/EntityInstance.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libbackend.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/ResourceLoader.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Mutex.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/PixelBufferDescriptor.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Options.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libstb.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libzstd.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformWebGL.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/vec4.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Invocable.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libktxreader.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/CallbackHandler.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/BufferObject.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/image/ColorTransform.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/tsl/robin_map.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/IndirectLight.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl/Cubemap.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/image/LinearImage.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/mathio filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/generic filter=lfs diff=lfs merge=lfs -text
ios/lib/filament-v1.31.6-ios.tgz filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filamat/Enums.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/uberz filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/CString.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/geometry filter=lfs diff=lfs merge=lfs -text
ios/lib/libibl.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libimageio.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/camutils/Bookmark.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/math.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/image/ImageSampler.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/image filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/StructureOfArrays.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/compiler.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libutils.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/DriverApiForward.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filamat/IncludeCallback.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/Frustum.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl/Image.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Path.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libpng.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/image/Ktx1Bundle.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ktxreader/Ktx2Reader.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilamat.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libutils.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/MorphTargetBuffer.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/norm.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/viewer/ViewerGui.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformWGL.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/MaterialInstance.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libdracodec.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/math/mat3.h filter=lfs diff=lfs merge=lfs -text
ios/lib/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libpng16.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/tsl/robin_hash.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/ostream.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
ios/lib/libcamutils.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformCocoaGL.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/geometry/TangentSpaceMesh.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/Animator.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/gltfio/MaterialProvider.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/FixedCapacityVector.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/debug.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libstb.a filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/unwindows.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/viewer filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/filament/MaterialChunkType.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/ibl/CubemapUtils.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/backend/platforms/PlatformEGLAndroid.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/include/utils/Log.h filter=lfs diff=lfs merge=lfs -text
ios/lib/filament/lib/universal/libimage.a filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libimage.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libktxreader.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libshaders.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libutils.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libimageio.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libzstd.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilament.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libgeometry.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libmatdbg.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libpng.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libviewer.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libdracodec.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libcamutils.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libibl.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libbackend.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libbluegl.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libbluevk.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libfilamat.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libgltfio.a filter=lfs diff=lfs merge=lfs -text
macos/lib/libstb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libz.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libdracodec.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilamat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libbluevk.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libcamutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libimageio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libbluevk.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libktxreader.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libcamutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libpng.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libz.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libgeometry.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libbackend.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libdracodec.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libpng.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libbackend.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilamat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libdracodec.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libbluevk.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libibl.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libzstd.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilamat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libimage.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libviewer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libstb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilament.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libibl.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libgeometry.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libzstd.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libgeometry.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libviewer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libgeometry.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libz.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libcamutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libz.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libstb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libibl.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libimageio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libktxreader.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libpng.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libibl.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libimage.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilamat.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libfilament.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libviewer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libimage.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libviewer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libfilament.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libimageio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libimageio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libktxreader.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libstb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libstb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libbackend.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libktxreader.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libcamutils.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilament.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libtinyexr.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libzstd.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libdracodec.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86/libzstd.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/armeabi-v7a/libpng.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libbluevk.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libimage.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/x86_64/libbackend.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilamat_lite.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libOSDependent.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilagui.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV-Tools-opt.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libbenchmark_main.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libglslang.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libbenchmark.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libgetopt.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libspirv-cross-msl.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV-Tools-diff.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libspirv-cross-glsl.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libOGLCompiler.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libgtest.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV-Tools-reduce.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libbasis_encoder.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libimgui.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libgeometry_combined.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV-Tools-link.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV-Tools-lint.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libSPIRV-Tools.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libfilamat_combined.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libmath.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libmathio.a filter=lfs diff=lfs merge=lfs -text
android/src/main/jniLibs/arm64-v8a/libspirv-cross-core.a filter=lfs diff=lfs merge=lfs -text
web/lib/libcivetweb.a filter=lfs diff=lfs merge=lfs -text
web/lib/libsmol-v.a filter=lfs diff=lfs merge=lfs -text
web/lib/libz.a filter=lfs diff=lfs merge=lfs -text
web/lib/libfilabridge.a filter=lfs diff=lfs merge=lfs -text
web/lib/libfilaflat.a filter=lfs diff=lfs merge=lfs -text
web/lib/libmathio.a filter=lfs diff=lfs merge=lfs -text
web/lib/libbackend.a filter=lfs diff=lfs merge=lfs -text
web/lib/libgeometry_combined.a filter=lfs diff=lfs merge=lfs -text
web/lib/libmeshoptimizer.a filter=lfs diff=lfs merge=lfs -text
web/lib/libutils.a filter=lfs diff=lfs merge=lfs -text
web/lib/libbasis_transcoder.a filter=lfs diff=lfs merge=lfs -text
web/lib/libimageio.a filter=lfs diff=lfs merge=lfs -text
web/lib/libktxreader.a filter=lfs diff=lfs merge=lfs -text
web/lib/libbasis_encoder.a filter=lfs diff=lfs merge=lfs -text
web/lib/libfilament.a filter=lfs diff=lfs merge=lfs -text
web/lib/libviewer.a filter=lfs diff=lfs merge=lfs -text
web/lib/libibl-lite.a filter=lfs diff=lfs merge=lfs -text
web/lib/libmath.a filter=lfs diff=lfs merge=lfs -text
web/lib/libstb.a filter=lfs diff=lfs merge=lfs -text
web/lib/libvkshaders.a filter=lfs diff=lfs merge=lfs -text
web/lib/libdracodec.a filter=lfs diff=lfs merge=lfs -text
web/lib/libfilameshio.a filter=lfs diff=lfs merge=lfs -text
web/lib/libgltfio_core.a filter=lfs diff=lfs merge=lfs -text
web/lib/libimgui.a filter=lfs diff=lfs merge=lfs -text
web/lib/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
web/lib/libzstd.a filter=lfs diff=lfs merge=lfs -text
web/lib/libuberarchive.a filter=lfs diff=lfs merge=lfs -text
web/lib/libuberzlib.a filter=lfs diff=lfs merge=lfs -text
web/lib/libcamutils.a filter=lfs diff=lfs merge=lfs -text
web/lib/libfilagui.a filter=lfs diff=lfs merge=lfs -text
web/lib/libfilament-iblprefilter.a filter=lfs diff=lfs merge=lfs -text
web/lib/libgtest.a filter=lfs diff=lfs merge=lfs -text
web/lib/libimage.a filter=lfs diff=lfs merge=lfs -text
web/lib/libshaders.a filter=lfs diff=lfs merge=lfs -text
assets/materials.uberz filter=lfs diff=lfs merge=lfs -text
assets/materials_ios_arm64.uberz filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/ filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/*.* filter=lfs diff=lfs merge=lfs -text
ios/lib/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/texture_test.png filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/scene.bin filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_baseColor4.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_occlusionRoughnessMetallic.png filter=lfs diff=lfs merge=lfs -text
example/assets/default_env filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/scene.gltf filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/shapes.gltf filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_baseColor1.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_baseColor2.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_occlusionRoughnessMetallic2.png filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/Boden_normal.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/body_baseColor.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/body_emissive.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/material_baseColor.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_occlusionRoughnessMetallic3.png filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/Boden_metallicRoughness.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_normal.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_normal1.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_normal3.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet.gltf filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_occlusionRoughnessMetallic4.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/README.md filter=lfs diff=lfs merge=lfs -text
example/assets/background.ktx filter=lfs diff=lfs merge=lfs -text
example/assets/default_env/default_env_skybox.ktx filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/shapes.blend filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/material_metallicRoughness.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_normal2.png filter=lfs diff=lfs merge=lfs -text
example/assets/background.png filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/shapes.bin filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/body_normal.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/material_normal.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_baseColor.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_normal4.png filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_occlusionRoughnessMetallic1.png filter=lfs diff=lfs merge=lfs -text
example/assets/default_env/default_env_ibl.ktx filter=lfs diff=lfs merge=lfs -text
example/assets/shapes/shapes.glb filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/Boden_baseColor.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/BusterDrone/textures/body_metallicRoughness.jpg filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet.bin filter=lfs diff=lfs merge=lfs -text
example/assets/FlightHelmet/FlightHelmet_baseColor3.png filter=lfs diff=lfs merge=lfs -text
assets/default.uberz filter=lfs diff=lfs merge=lfs -text
windows/lib/**/*.* filter=lfs diff=lfs merge=lfs -text
windows/lib/Debug/angle/* filter=lfs diff=lfs merge=lfs -text
windows/lib/Debug/opengl/* filter=lfs diff=lfs merge=lfs -text
windows/lib/Release/opengl/* filter=lfs diff=lfs merge=lfs -text
windows/lib/Release/angle/* filter=lfs diff=lfs merge=lfs -text
windows/lib/**/* filter=lfs diff=lfs merge=lfs -text
*.lib filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.pdb filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.uberz filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.ktx filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.gltf filter=lfs diff=lfs merge=lfs -text
*.glb filter=lfs diff=lfs merge=lfs -text

29
.github/workflows/analyze_project.yaml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Dart Analyzer
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: '12.x'
- name: Install Flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '2.x'
- name: Get dependencies
run: flutter pub get
- name: Analyze
run: flutter analyze

View File

@@ -0,0 +1,35 @@
name: PubDev Score
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
package-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: axel-op/dart-package-analyzer@v3
id: analysis
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
# use this id to retrieve the outputs in the next steps
# exit dirty when the package doesn't reach 100%
- name: Check scores
env:
# "analysis" is the id set above
# PERCENTAGE=$(( $TOTAL * 100 / $TOTAL_MAX ))
TOTAL: ${{ steps.analysis.outputs.total }}
TOTAL_MAX: ${{ steps.analysis.outputs.total_max }}
JSON_OUT: ${{ steps.analysis.outputs.json_output }}
run: |
if (( $TOTAL != $TOTAL_MAX ))
then
echo There are missing points in the project!
echo $TOTAL from $TOTAL_MAX Points reached
echo $JSON_OUT | jq
exit 1
fi

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.vscode
macos/src
macos/include
.DS_Store

36
ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,36 @@
# Rendering/plugin architecture
This is an overview of how the rendering surface is constructed, and how the Flutter plugin communicates with the Filament renderer. If you are looking to extend the plugin or add (and hopefully contribute back upstream) additional features, start here.
## Rendering surface
|Platform|Type|
|---|---|
|Windows|HWND beneath transparency (OpenGL), glTexture render target + Flutter Texture widget (GLES/ANGLE), glTexture render target + Flutter Texture widget (GLES/ANGLE)|
|Android|SurfaceTexture render target + Flutter Texture widget|
|iOS|CVPixelBuffer surface (Metal) + Flutter Texture widget|
|MacOS|CVMetalTexture render target (Metal) + Flutter Texture widget|
On most platforms, we create Filament with a headless swapchain, then render into a (hardware accelerated) texture that Flutter imports into its own widget hierarchy via a Texture widget. This allows the Filament viewport to be transformed/composed completely within the Flutter hierarchy (i.e. you could rotate/scale/translate the FilamentWidget in Flutter if you wanted, or insert other widgets above/below).
Due to performance issues on Windows, we choose a different default approach where Filament renders into its own window, which is then composed with the Flutter window via the system compositor. This only works on Windows 10.
Using this approach, you will not be able to add a Flutter widget behind the Filament viewport, or transform the viewport itself from within Flutter.
You can fall-back to the Texture/render target approach by setting `WGL_USE_BACKING_WINDOW` to `false` in `CMakeLists.txt` for Windows.
However, I don't currently have capacity to maintain this pathway so it will probably be broken on any given day.
If you want to try the fallback, you have two options for a rendering backend. With `USE_ANGLE` set to `true` in `CMakeLists.txt`, we will use the ANGLE backend (which translates GLES calls to D3D). This provides end-to-end GPU texture support, however there are some odd rendering artifacts with some of the Filament shaders (and in fact will crash with some dynamic lights).
`USE_ANGLE` set to `false` will use the OpenGL backend, but requires copying the contents of the texture from the GPU to CPU on every frame. This is not optimal for performance.
### Why not Platform Views?
Initially, performance of Platform Views was inferior to Texture widgets (and in any case, weren't supported on Windows/Linux). I suspect this is still the case (though that might be worth revisiting).
However, I am now thinking it would be better to lean towards the current Windows model (where the Flutter app is composited over a Filament viewport running in a separate window or view). I suspect that the overwhelming use case is a Flutter UI sitting on top of a Filament viewport, and that very few people will need to insert widgets beneath the viewport (or transform the viewport from within Flutter, excluding resizes or mobile orientation changes which can be handled independently). Deferring to the system compositor should deliver far better performance, at the cost of slightly more complexity in the setting up the app harness.
## Flutter <-> Platform <-> FFI
TODO

View File

@@ -1,3 +1,9 @@
## 0.0.1
## 0.6.0
* TODO: Describe initial release.
* `createViewer` is no longer called by `FilamentWidget` and must be called manually at least one frame after a FilamentWidget has been inserted into the widget hierarchy.
## 0.5.0
* Replaced `isReadyForScene` Future in `FilamentController` with the `Stream<bool>` `hasViewer`.
* Rendering is set to false when the app is hidden, inactive or paused; on resume, this will be set to the value it held prior to being hidden/inactive/paused.

27
Makefile Normal file
View File

@@ -0,0 +1,27 @@
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(dir $(mkfile_path))
parent_dir := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/..)
filament_build_out := $(parent_dir)/filament/out/cmake-release
# building on MacOS, we currently just delete the macos/include
# and macos/src directories and copy from iOS
sync-macos: FORCE
rm -rf ${current_dir}macos/include ${current_dir}macos/src
cp -R ${current_dir}ios/include ${current_dir}macos
cp -R ${current_dir}ios/src ${current_dir}macos
FORCE: ;
# We use a single material (no lighting and no transparency) for background images
#
# by default this assumes you have built filament in a sibling folder
# you may customize the out folder by speicifying `filament_build_out`
#
# eg: make generate-background-material filament_build_out=/filament/out/release
#
generate-background-material:
${filament_build_out}/tools/matc/matc -a opengl -a metal -o materials/image.filamat materials/image.mat
${filament_build_out}/tools/resgen/resgen -c -p image -x ios/include/material/ materials/image.filamat
rm materials/image.filamat

306
README.md
View File

@@ -1,46 +1,40 @@
# Flutter Filament
Cross-platform, Physically-based rendering inside Flutter applications.
Cross-platform, 3D PBR rendering and animation for [Flutter](https://github.com/google/filament).
Flutter plugin wrapping the Filament renderer https://github.com/google/filament.
Wraps the [the Filament rendering library](https://github.com/google/filament).
Powers the Polyvox and odd-io engines.
Powers the [Polyvox](https://polyvox.app) and [odd-io](https://github.com/odd-io/) engines.
# Sponsors
This is still in beta: bugs/missing features are to be expected.
Thank you to odd-io for sponsoring work on supporting Windows, raycasting, testing and documentation.
https://github.com/nmfisher/flutter_filament/assets/7238578/abaed1c8-c97b-4999-97b2-39e85e0fa7dd
# Overview
## Versioning
|Feature|Supported|
|---|---|
|Platforms|✅ iOS (arm64)<br/>✅ MacOS (arm64)<br/>✅ Android (arm64) <br/>✅ Windows (x64) (>= 10)<br/>⚠️ Linux (x64 - broken)<br/>⚠️ Web (planned)|
|Formats|✅ glb <br/>⚠️ glTF (partial - see Known Issues)|
|Texture support|✅ PNG <br/>✅ JPEG <br/>✅ KTX <br/>⚠️ KTX2 (planned)|
|Camera movement|✅ Desktop (mouse)<br/>✅ Mobile (swipe/pinch)|
|Animation|✅ Embedded glTF skinning animations<br/>✅ Embedded glTF morph animations<br/> ✅ Runtime/dynamic morph animations<br/> ⚠️ Runtime/dynamic skinning animations <br/>
|Entity manipulation|✅ Viewport selection<br/>⚠️ Entity/transform parenting (planned)<br/> ⚠️ Transform manipulation (mouse/gesture to rotate/translate/scale object) (partial)<br/>⚠️ Runtime material changes (planned)|
Special thanks to [odd-io](https://github.com/odd-io/) for sponsoring work on supporting Windows, raycasting, testing and documentation.
PRs are welcome but please create a placeholder PR to discuss before writing any code. This will help with feature planning, avoid clashes with existing work and keep the project structure consistent.
## Getting Started
This package requires Flutter >= `3.16.0-0.2.pre`, so you will need to first switch to the `beta` channel:
Last tested on Flutter `3.15.0-15.2.pre`. This is on the Flutter beta channel, so run:
```
flutter channel beta
flutter upgrade
```
There are specific issues with earlier versions on Windows/MacOS (mobile should actually be fine, so if you want to experiment on your own you're free to remove the minimum version from `pubspec.yaml`).
||Android|iOS|MacOS|Windows|Linux|WebGL
|---|---|---|---|---|---||
|Filament|v1.43.1 (arm64/armeabi-v7a/x86/x86_64)|v1.43.1* (arm64)|v1.43.1 (arm64)|v1.32.4 (x86_64)|TODO**|TODO***|
|Flutter||3.15.0-15.2.pre|3.15.0-15.2.pre|3.15.0-15.2.pre
* iOS release build has a skybox bug so the debug versions are currently shipped on iOS
** (Waiting for https://github.com/google/filament/issues/7078 to be resolved before upgrading, not sure exactly when the bug was introduced but it was somewhere between v1.32.4 and v1.40.0)
*** Texture widget not currently supported on web in Flutter.
## Features
|Feature|Supported|
|---|---|
|glTF|Y|
|glb|Y|
# Basic Setup
## Clone flutter_filament
This plugin is not yet published to pub.dev. To use in your project, simply clone the repository and pull the latest binaries from Git LFS:
Next, clone this repository and pull the latest binaries from Git LFS:
```
cd $HOME
@@ -48,17 +42,17 @@ git clone <repo> && cd flutter_filament
git lfs pull
```
You *do not need to build Filament yourself*. The repository is bundled with all necessary headers/static libraries (`windows/lib`, `ios/lib`, `macos/lib` and `linux/lib`) and the Flutter plugin has been configured to link at build time.
(this step won't be needed after the plugin is published to pub.dev).
If you want to run the example project to check:
> You *do not need to build Filament yourself*. The repository is bundled with all necessary headers/static libraries (`windows/lib`, `ios/lib`, `macos/lib` and `linux/lib`) and the Flutter plugin has been configured to link at build time.
Run the example project to check:
```
cd example && flutter run -d <macos/windows/Your iPhone/etc>
```
## Add dependency
Add the plugin as a dependency in the pubspec.yaml for your application:
To use the plugin in your own project, add the plugin to your pubspec.yaml:
```
name: your_project
@@ -71,15 +65,14 @@ dependencies:
path: <path where you cloned the repository>
```
# Basic Usage
## Basic Usage
See the `example` project for a complete sample of the below steps.
See the `example` project for a complete sample that incorporates many of the below steps, and more.
## Creating the viewport widget and controller
### Creating the viewport widget and controller
To embed a viewport in your app, create an instance of `FilamentControllerFFI` somewhere in your app:
Create an instance of `FilamentControllerFFI` somewhere in your app where it will not be garbage collected until you no longer need a rendering canvas:
e.g.
```
class MyApp extends StatelessWidget {
@@ -88,11 +81,10 @@ class MyApp extends StatelessWidget {
}
```
Constructing this object only load symbols from the native FFI library.
(Note this is not (yet) a singleton, so ensure it is placed somewhere in the widget hierachy where it will not be garbage-collected until you no longer need a rendering canvas).
This is a relatively lightweight object, however its constructor will load/bind symbols from the native library. This may momentarily block the UI, so you may wish to structure your app so that this is hidden behind a static widget until it is available.
Next, create an instance of `FilamentWidget` in the widget hierarchy where you want the rendering canvas to appear. This can be sized as large or as small as you want. Flutter widgets can be positioned above or below the `FilamentWidget`.
Next, create an instance of `FilamentWidget` in the widget hierarchy where you want the rendering canvas to appear. This can be sized as large or as small as you want. On most platforms, Flutter widgets can be positioned above or below the `FilamentWidget`.
```
class MyApp extends StatelessWidget {
@@ -113,21 +105,54 @@ class MyApp extends StatelessWidget {
```
When a `FilamentWidget` is added to the widget hierarchy:
1) on the first frame, by default a Container will be rendered with solid red. If you want to change this, pass a widget as the `initial` paramer to the `FilamentWidget` constructor.
2) on the second frame, `FilamentWidget` will retrieve its actual size and request the `FilamentController` to create:
a) the backing textures needed to insert a `Texture` widget into
b) a rendering thread
c) a `FilamentViewer` and an `AssetManager`, which will allow you to load assets/cameras/lighting/etc via the `FilamentController`
1) by default a Container will be rendered with solid red. If you want to change this, pass a widget as the `initial` paramer to the `FilamentWidget` constructor.
2) on the second frame, `FilamentWidget` will pass its dimensions/pixel ratio to the `FilamentController`
3) You can then call `createViewer` to create:
* the rendering surface (on most platforms, a backing texture that will be registered with Flutter for use in a `Texture` widget)
* a rendering thread
* a `FilamentViewer` and an `AssetManager`, which will allow you to load assets/cameras/lighting/etc via the `FilamentController`
4) after an indeterminate number of frames, `FilamentController` will notify `FilamentWidget` when a rendering surface is available the viewport
5) `FilamentWidget` will replace the default `initial` Widget with the viewport (which will initially be solid black or white, depending on your platform).
If this was successful, the viewport should turn from red to black.
IMPORTANT: there *will* be a delay between adding a `FilamentWidget`, calling `createViewer` and the actual rendering viewport becoming available. This is why we fill `FilamentWidget` with red - to make it abundantly clear that you need to handle this asynchronous delay appropriately. Once `createViewer` has completed, the viewport is available for rendering.
### Rendering
> Currently, the `initial` widget will also be displayed whenever the viewport is resized (including changing orientation on mobile and drag-to-resize on desktop). You probably want to change this from the default red.
Congratulations! You now have a scene. It's completely empty, so you probably want to add something visible.
### Load a background
You probably want to set a background for your scene. You can load a skybox:
```
await _filamentController.loadSkybox("assets/default_env/default_env_skybox.ktx)
```
or a static background image:
```
await _filamentController.setBackgroundImage("assets/background.ktx)
```
or a solid background color:
```
await _filamentController.setBackgroundColor(0.0, 1.0, 0.0, 1.0); // solid green
```
At this point, you might not see any change in the viewport. This is because the FilamentController will only actually render into the viewport once `render` has been called.
By default, the FilamentController will only render into the viewport by manually calling `render()` on the FilamentController. This is to avoid needlessly running a render loop when there is nothing to display.
To automatically render at 60fps, call `setRendering(true)` on `FilamentController`.
```
await _filamentController.render()
```
### Assets
You should now see your background displayed in the scene. To automatically render at 60fps, call `setRendering`:
```
await _filamentController.setRendering(true);
```
### Load an asset
To add a glTF asset to the scene, call `loadGlb()` on `FilamentController` with the Flutter asset path to your .glb file.
@@ -140,19 +165,44 @@ flutter:
Then you would call the following
```
var entity = _filamentController.loadGlb("assets/models/bob.glb");
var entity = await _filamentController.loadGlb("assets/models/bob.glb");
```
You can also pass a URI to indicate that the glTF file should be loaded from the filesystem:
```
var entity = _filamentController.loadGlb("file:///tmp/bob.glb");
var entity = await _filamentController.loadGlb("file:///tmp/bob.glb");
```
The returned value is an integer handle that be used to manipulate the asset (better referred to as the "entity") in the scene.
E.g. to remove the asset:
The return type `FilamentEntity` is simply an integer handle that be used to manipulate the entity in the scene. For example, to remove the asset:
```
_filamentController.removeAsset(entity);
await _filamentController.removeAsset(entity);
entity = null;
```
> Removing an entity from the scene will invalidate the corresponding `FilamentEntity` handle, so ensure you don't retain any references to it after calling `removeAsset` or `clearAssets`. Removing one `FilamentEntity` does not invalidate/change any other `FilamentEntity` handles; you can continue to safely manipulate these via the `FilamentController`.
### Lighting
You should now see your object in the viewport, but since we haven't added a light, this will be solid black.
Add an image-based light from a KTX file:
```
await _filamentController.loadIbl("assets/default_env/default_env_ibl.ktx");
```
You can also add dynamic lights:
```
var sun = await _filamentController.addLight(
```
### Manipulating entity transforms
To set the world space position of the asset:
```
_filamentController.setPositon(entity, 1.0, 1.0, 1.0);
```
On desktop, you can also click any renderable object in the viewport to retrieve its associated FilamentEntity (see below).
### Camera movement
@@ -168,8 +218,7 @@ class MyApp extends StatelessWidget {
return MaterialApp(
color: Colors.white,
home: Scaffold(backgroundColor: Colors.white, body: Stack(children:[
Container(color:Colors.green, height:100, width:100),
Positioned.fill(top:100, left:100,child:FilamentGestureDetector(
Positioned.fill(child:FilamentGestureDetector(
controller: _filamentController,
child:FilamentWidget(
controller:_filamentController
@@ -180,6 +229,69 @@ class MyApp extends StatelessWidget {
}
```
On desktop:
1) hold the middle mouse button and move the mouse to rotate the camera
2) hold the left mouse button and move the mouse to pan the camera
3) scroll up/down with the scrollwheel to zoom in/out.
On mobile:
1) swipe with your finger to pan the camera
2) double tap the viewport, then swipe with your finger to rotate the camera (double-tap again to return to pan)
3) pinch with two fingers in/out to zoom in/out.
### Changing the active camera
Every scene has a default camera. Whenever you rotate/pan/zoom the viewport, you are moving the default camera.
If you have added an entity to the scene that contains one or more camera nodes, you can change the active scene camera to one of those camera nodes.
```
var asset = await _filamentController.loadGlb("assets/some_asset_with_camera.glb");
await _filamentController.setCamera(asset, "Camera.002"); // pass the node name to load a specific camera under that entity node
await _filamentController.setCamera(asset, null); // pass null to load the first camera found under that entity
```
### Picking entities
On desktop, left-clicking an object in the viewport will retrieve the FilamentEntity for the top-most renderable instance at that cursor position (if any).
Note this is an asynchronous operation, so you will need to subscribe to the [pickResult] stream on your [FilamentController] to do something with the result.
```
class MyApp extends StatefulWidget {
...
}
class _MyAppState extends State<MyApp> {
final _filamentController = FilamentControllerFFI();
@override
void initState() {
_filamentController.pickResult.listen((FilamentEntity filamentEntity) async {
var entityName = _filamentController.getNameForEntity(filamentEntity);
await showDialog(builder:(ctx) {
return Container(child:Text("You clicked $entityName"));
});
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.white,
home: Scaffold(backgroundColor: Colors.white, body: Stack(children:[
Positioned.fill(child:FilamentGestureDetector(
controller: _filamentController,
child:FilamentWidget(
controller:_filamentController
))),
])));
}
}
```
## Advanced Usage
If you want to work with custom materials, you will need some (basic knowledge of the underlying Filament library)[https://google.github.io/filament/Materials.html#compilingmaterials].
@@ -196,7 +308,53 @@ uberz -TSHADINGMODEL=lit -TBLENDING=opaque -o lit_opaque_43.uberz lit_opaque
(note that the number in the filename corresponds to the Material version, not the Filament version. Not every Filament version requires a new Material version).
## Footguns
### Stripping in release mode
If you build your app in release mode, you will need to ensure that "Dead Strip" is set to false.
This is because we only invoke the library at runtime via FFI, so at link time these symbols are otherwise treated as redundant.
### Animations when backgrounded
Don't call playAnimation when the app is in the background (i.e inactive/hidden). This will queue, but not start, an animation, and eventually this will overflow the command buffer when the app is foregrounded/resumed.
If you have some kind of looping animation in your app code, make sure it pauses while the app is backgrounded.
## Versioning
||Android|iOS|MacOS|Windows|Linux|WebGL|
|---|---|---|---|---|---||
|Filament|v1.43.1 (arm64/armeabi-v7a/x86/x86_64)|v1.43.1* (arm64)|v1.43.1 (arm64)|v1.32.4 (x86_64)|TODO**|TODO***|
|Flutter||3.15.0-15.2.pre|3.15.0-15.2.pre|3.15.0-15.2.pre
* iOS release build has a skybox bug so the debug versions are currently shipped on iOS
** (Waiting for https://github.com/google/filament/issues/7078 to be resolved before upgrading, not sure exactly when the bug was introduced but it was somewhere between v1.32.4 and v1.40.0)
*** Texture widget not currently supported on web in Flutter.
## Testing
We automate testing by running the example project on actual iOS/Android/MacOS/Windows devices and executing various operations.
Eventually we want to compare screenshots after each operation to a set of goldens for every platform.
Currently this is only possible on iOS (see https://github.com/flutter/flutter/issues/123063 and https://github.com/flutter/flutter/issues/127306).
To re-generate the golden screenshots for a given device:
```
./regenerate_goldens.sh <your_device_id>
```
To run the tests and compare against those goldens:
```
./compare_goldens.sh <your_device_id>
```
The results will depend on the actual device used to generate the golden, therefore if you are using a different device (which is likely), your results may not be the same. This is expected.
# Building Filament from source
@@ -204,6 +362,13 @@ uberz -TSHADINGMODEL=lit -TBLENDING=opaque -o lit_opaque_43.uberz lit_opaque
git clone git@github.com:nmfisher/filament.git && cd filament
```
## Android/iOS/MacOS
```
git checkout flutter-filament-ios-android-macos
./build.sh -p <platform> release
```
## Windows
To support embedding GPU textures in Flutter (rather than copying to a CPU pixel buffer on every frame), we need to build a slightly customized version of Filament that uses GLES on Windows (rather than the default, which uses OpenGL).
@@ -213,9 +378,9 @@ Separately, we also force the Filament gltfio library to load assets via in-memo
```
git checkout flutter-filament-windows
mkdir out && cd out
"C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --build . --target gltf_viewer --config Debug
```
Building notes:
On Android/iOS, we remove -fno-exceptions from CMakeLists.txt
@@ -223,10 +388,10 @@ Project structure:
- most shared code/headers under ios/src (because I still can't get podspec to build a target with symlinks or relative paths)
- building on MacOS, we currently just delete the macos/include and macos/src directories and copy from iOS (for same reason),
e.g.
`rm -r ../macos/include && cp -R ../ios/include ../macos && rm -r ../macos/src && cp -R ../ios/src ../macos && pushd macos && pod update && popd && flutter run -d macos`
- Android keeps a separate copy of ALL headers (because it's currently running a different version of Filament, earlier versions have some texture filtering issues)
-- can't symlink either?
--- IMPORTANT - current version only works on Flutter 3.15.0-15.2.pre / Filament v1.43.1
```
make sync-macos
```
- Note also need to specifically build imageio/png/tinyexr
- if release build, then need to comment out -fno-exceptions
@@ -249,19 +414,20 @@ EMCC_CFLAGS="-I/Users/nickfisher/Documents/filament/libs/utils/include -I/Users/
## Materials
glTF assets The default
We use a single material (no lighting and no transparency) for background images:
- there is a simple material (unlit/opaque) used for background images. This is created by:
```
filament/out/release/filament/bin/matc -a opengl -a metal -o materials/image.filamat materials/image.mat
filament/out/release/filament/bin/resgen -c -p image -x ios/include/material/ materials/image.filamat
make generate-background-material
```
# Known issues
On Windows, loading a glTF (but NOT a glb) may crash due to a race condition between uploading resource data to GPU memory and being freed on the host side.
This has been fixed in recent versions of Filament, but other bugs on Windows prevent upgrading.
Only workaround is to load a .glb file.
Only workaround is to load a .glb file.
# Thanks
- https://github.com/alexmercerind/flutter-windows-ANGLE-OpenGL-ES

View File

@@ -0,0 +1,8 @@
{
"allAbis": [
"arm64-v8a"
],
"validAbis": [
"ARM64_V8A"
]
}

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,20 @@
{
"ndkHandlerSupportedAbis": [
"ARMEABI_V7A",
"ARM64_V8A",
"X86",
"X86_64"
],
"ndkHandlerDefaultAbis": [
"ARMEABI_V7A",
"ARM64_V8A",
"X86",
"X86_64"
],
"externalNativeBuildAbiFilters": [],
"ndkConfigAbiFilters": [
"arm64-v8a"
],
"splitsFilterAbis": [],
"ideBuildOnlyTargetAbi": true
}

View File

@@ -0,0 +1,11 @@
{
"ndk": "C:\\Users\\Nick\\AppData\\Local\\Android\\Sdk\\ndk\\25.2.9519653",
"revision": {
"mMajor": 25,
"mMinor": 2,
"mMicro": 9519653,
"mPreview": 0,
"mPrecision": "MICRO",
"mPreviewSeparator": " "
}
}

View File

@@ -0,0 +1,22 @@
[
{
"level": "INFO",
"message": "android.ndkVersion from module build.gradle is [25.2.9519653]"
},
{
"level": "INFO",
"message": "android.ndkPath from module build.gradle is not set"
},
{
"level": "INFO",
"message": "ndk.dir in local.properties is not set"
},
{
"level": "INFO",
"message": "Not considering ANDROID_NDK_HOME because support was removed after deprecation period."
},
{
"level": "INFO",
"message": "sdkFolder is C:\\Users\\Nick\\AppData\\Local\\Android\\Sdk"
}
]

View File

@@ -0,0 +1,17 @@
{
"ndkVersionFromDsl": "25.2.9519653",
"sdkFolder": "C:\\Users\\Nick\\AppData\\Local\\Android\\Sdk",
"sideBySideNdkFolderNames": [
"19.2.5345600",
"21.1.6352462",
"21.4.7075529",
"22.0.7026061",
"22.1.7171670",
"23.0.7599858",
"23.1.7779620",
"23.2.8568313",
"24.0.8215888",
"25.1.8937393",
"25.2.9519653"
]
}

View File

@@ -7,9 +7,9 @@ include_directories(src/main/cpp)
link_directories(src/main/jniLibs/${ANDROID_ABI})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
add_library(polyvox_filament_android SHARED
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/PolyvoxFilamentApi.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/PolyvoxFilamentFFIApi.cpp"
add_library(flutter_filament_android SHARED
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/FlutterFilamentApi.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/FlutterFilamentFFIApi.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/FilamentAndroid.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/AssetManager.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/FilamentViewer.cpp"
@@ -24,7 +24,7 @@ add_library(FILAMENT_SHADERS SHARED
)
target_link_libraries(
polyvox_filament_android
flutter_filament_android
FILAMENT_SHADERS
-landroid
-llog

View File

@@ -1 +1 @@
rootProject.name = 'polyvox_filament'
rootProject.name = 'flutter_filament'

View File

@@ -3,7 +3,7 @@
extern "C" {
#include "PolyvoxFilamentFFIApi.h"
#include "FlutterFilamentFFIApi.h"
void* get_native_window_from_surface(
jobject surface,

View File

@@ -26,21 +26,21 @@ import io.flutter.view.TextureRegistry.SurfaceTextureEntry
import java.io.File
import java.util.*
class LoadFilamentResourceFromOwnerImpl(plugin:PolyvoxFilamentPlugin) : LoadFilamentResourceFromOwner {
class LoadFilamentResourceFromOwnerImpl(plugin:FlutterFilamentPlugin) : LoadFilamentResourceFromOwner {
var plugin = plugin
override fun loadResourceFromOwner(path: String?, owner: Pointer?): ResourceBuffer {
return plugin.loadResourceFromOwner(path, owner)
}
}
class FreeFilamentResourceFromOwnerImpl(plugin:PolyvoxFilamentPlugin) : FreeFilamentResourceFromOwner {
class FreeFilamentResourceFromOwnerImpl(plugin:FlutterFilamentPlugin) : FreeFilamentResourceFromOwner {
var plugin = plugin
override fun freeResourceFromOwner(rb: ResourceBuffer, owner: Pointer?) {
plugin.freeResourceFromOwner(rb, owner)
}
}
class RenderCallbackImpl(plugin:PolyvoxFilamentPlugin) : RenderCallback {
class RenderCallbackImpl(plugin:FlutterFilamentPlugin) : RenderCallback {
var plugin = plugin
override fun renderCallback(owner:Pointer?) {
plugin.renderCallback();
@@ -51,8 +51,8 @@ class RenderCallbackImpl(plugin:PolyvoxFilamentPlugin) : RenderCallback {
}
}
/** PolyvoxFilamentPlugin */
class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, LoadFilamentResourceFromOwner, FreeFilamentResourceFromOwner {
/** FlutterFilamentPlugin */
class FlutterFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, LoadFilamentResourceFromOwner, FreeFilamentResourceFromOwner {
companion object {
const val CHANNEL_NAME = "app.polyvox.filament/event"
@@ -80,7 +80,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
this.flutterPluginBinding = flutterPluginBinding
channel = MethodChannel(flutterPluginBinding.binaryMessenger, CHANNEL_NAME)
channel.setMethodCallHandler(this)
_lib = Native.loadLibrary("polyvox_filament_android", FilamentInterop::class.java, Collections.singletonMap(Library.OPTION_ALLOW_OBJECTS, true))
_lib = Native.loadLibrary("flutter_filament_android", FilamentInterop::class.java, Collections.singletonMap(Library.OPTION_ALLOW_OBJECTS, true))
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
@@ -93,7 +93,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
var _lastId = 1
override fun loadResourceFromOwner(path: String?, owner: Pointer?): ResourceBuffer {
Log.i("polyvox_filament", "Loading resource from path $path")
Log.i("flutter_filament", "Loading resource from path $path")
var data:ByteArray? = null
if(path!!.startsWith("file://")) {
data = File(path!!.substring(6)).readBytes()
@@ -108,14 +108,14 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
if (hotReloadPath != null) {
data = File(hotReloadPath).readBytes()
} else {
Log.i("polyvox_filament", "Loading resource from main asset bundle at ${assetPath}")
Log.i("flutter_filament", "Loading resource from main asset bundle at ${assetPath}")
val assetManager: AssetManager = activity.assets
try {
data = assetManager.open(key).readBytes()
Log.i("polyvox_filament", "Loaded ${data.size} bytes")
Log.i("flutter_filament", "Loaded ${data.size} bytes")
} catch (e:Exception) {
Log.e("polyvox_filament", "Failed to open asset at ${assetPath}", null)
Log.e("flutter_filament", "Failed to open asset at ${assetPath}", null)
}
}
}
@@ -135,7 +135,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
rb.data = Pointer(0)
}
} catch(e:Exception) {
Log.e("polyvox_filament", "Error setting resource buffer : $e", null);
Log.e("flutter_filament", "Error setting resource buffer : $e", null);
}
rb.write();
return rb;
@@ -153,11 +153,8 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
@RequiresApi(Build.VERSION_CODES.M)
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
Log.e("polyvox_filament", call.method, null)
Log.e("flutter_filament", call.method, null)
when (call.method) {
"getSharedContext" -> {
result.success(null)
}
"createTexture" -> {
if(_surfaceTextureEntry != null) {
result.error("TEXTURE_EXISTS", "Texture already exist. Make sure you call destroyTexture first", null)
@@ -170,7 +167,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
result.error("DIMENSION_MISMATCH","Both dimensions must be greater than zero (you provided $width x $height)", null);
return;
}
Log.i("polyvox_filament", "Creating Surface Texture of size ${width}x${height}");
Log.i("flutter_filament", "Creating Surface Texture of size ${width}x${height}");
_surfaceTextureEntry = flutterPluginBinding.textureRegistry.createSurfaceTexture()
_surfaceTexture = _surfaceTextureEntry!!.surfaceTexture();
@@ -184,7 +181,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
val nativeWindow = _lib.get_native_window_from_surface(_surface!! as Object, JNIEnv.CURRENT)
val resultList = listOf(_surfaceTextureEntry!!.id(), Pointer.nativeValue(nativeWindow), null )
val resultList = listOf(_surfaceTextureEntry!!.id(), Pointer.nativeValue(nativeWindow), null, null )
result.success(resultList)
}
@@ -201,16 +198,8 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo
_surfaceTextureEntry!!.release();
_surface = null
_surfaceTextureEntry = null
result.success(true)
}
"resize" -> {
val args = call.arguments as List<Any>
val width = args[0] as Int
val height = args[1] as Int
val scale = args[2] as Double
_surfaceTexture!!.setDefaultBufferSize(width, height)
Log.i(TAG, "Resized to ${args[0]}x${args[1]}")
result.success(_surfaceTexture)
}
else -> {
result.notImplemented()
}

View File

@@ -11,17 +11,17 @@ class HotReloadPathHelper {
companion object {
fun getAssetPath(path: String, packageName: String): String? {
val packagePath = "/data/user/0/${packageName}/code_cache/"
Log.v("polyvox_filament", "Looking for hot reloaded asset ${path} under package path ${packagePath}")
Log.v("flutter_filament", "Looking for hot reloaded asset ${path} under package path ${packagePath}")
val files = File(packagePath).walkBottomUp().filter {
it.path.endsWith(path)
}.sortedBy {
it.lastModified()
}.toList()
if(files.size > 0) {
Log.v("polyvox_filament", "Using hot reloaded asset at ${files.last().path}")
Log.v("flutter_filament", "Using hot reloaded asset at ${files.last().path}")
return files.last().path;
}
Log.v("polyvox_filament", "No hot reloaded asset found.")
Log.v("flutter_filament", "No hot reloaded asset found.")
return null;
}
}

View File

@@ -0,0 +1,4 @@
{
"flutterSdkVersion": "3.16.0-0.2.pre",
"flavors": {}
}

View File

@@ -3,3 +3,28 @@ assets/BusterDrone filter=lfs diff=lfs merge=lfs -text
assets/FlightHelmet filter=lfs diff=lfs merge=lfs -text
assets/lit_opaque_32.uberz filter=lfs diff=lfs merge=lfs -text
windows/lib/**/*.* filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/12_Settonemappingtolinear.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/3_loadIBL.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/6_zoomin.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/13_Movecameratoasset.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/14_movecamerato.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/7_rotate.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/9_transformtounitcube.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/0_fresh.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/10_setshapespositionto.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/2_loadskybox.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/4_Renderingfalse.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/8_pan.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/11_Disablefrustumculling.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/15_setcameratofirstcamerainshapesGLB.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/1_createviewerdefaultubershader.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/5_loadshapesGLB.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/16_resize.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/3_loadskybox.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/4_loadIBL.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/19_resize.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/17_resize.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/2_Renderingfalse.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/18_resize.png filter=lfs diff=lfs merge=lfs -text
integration_test/goldens/ios/diffs filter=lfs diff=lfs merge=lfs -text

3
example/.gitignore vendored
View File

@@ -46,3 +46,6 @@ app.*.map.json
/android/app/release
/android/.cxx/**/*
# fvm
.fvm/flutter_sdk

View File

@@ -1,6 +1,6 @@
# polyvox_filament_example
# flutter_filament_example
Demonstrates how to use the polyvox_filament plugin.
Demonstrates how to use the flutter_filament plugin.
## Linux

View File

@@ -45,7 +45,7 @@ android {
}
defaultConfig {
applicationId "app.polyvox.filament_example"
applicationId "app.polyvox.flutter_filament_example"
minSdkVersion 22
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()

View File

@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.polyvox.filament_example">
package="app.polyvox.flutter_filament_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

View File

@@ -1,8 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.polyvox.filament_example">
package="app.polyvox.flutter_filament_example">
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
android:name="${applicationName}"
android:label="polyvox_filament_example"
android:label="flutter_filament_example"
android:icon="@mipmap/ic_launcher"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
>

View File

@@ -1,4 +1,4 @@
package app.polyvox.filament_example
package app.polyvox.flutter_filament_example
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.TransparencyMode

View File

@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.polyvox.filament_example">
package="app.polyvox.flutter_filament_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cded95729bd217f86db59866042260dd8049bbff25bbde8fb52f37bd605653fa
size 212643

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d7a46bb2bec8300cb9fcd41a9bd0fecd38c17732ff5afaaa54136c9d1d578a65
size 2596038

View File

@@ -0,0 +1,9 @@
#!/bin/bash
device=$1
if [ -z "$device" ]; then
echo "Usage: $0 <device_id>"
exit 1;
fi
rm -f integration_test/goldens/{ios,macos,windows,android}/diffs/*.png
flutter drive --driver=test_driver/integration_test.dart -d $1 --target=integration_test/plugin_integration_test.dart

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ec2a9627f23ffe07750323c25afa78c6c7fcb7d26b5ed36d119363ced0b60f29
size 258304

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:53256c9443c6d36edfb8c1234711173c847126e888d714151ae026c57495fe6b
size 1875814

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b0c715cadbf84c2161099e8373a404c7d6dbb093faf4157aa0e0aa3825c28217
size 1868778

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56a431b561db7038ad7fe92d025fc2fe2806dfa2cf68c29a0380c3cbd2b66fb5
size 1742539

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:14193a392baf348f77895ca7bfb8cee160407c762d03c01bf1f7b5b771a9b1ab
size 2282401

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:77badd0b2a59122949e497297052064c403006272daa4488db43e492d60093e2
size 1959141

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bdf63e19e5a992f2c848cf71b55ceddf8930d6a9368c9b3adcc13e7c478c7146
size 1889777

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:651c19434ae3753488eb840695955b98db9d66a20b79bee1e21b3384c2358025
size 1609541

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f11462c0fdf30d101b6ed6c430734adcf6451818f3c7824126c8423014836773
size 2060944

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:beb941d33777ad2e1d6ef3704ba6a63b3a5608ca885a516a1c9e807a31b533fc
size 1608407

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2bcae11fd2eb593c419a62731e1799f7340408b28ad56575fab5f79db608ae17
size 2062339

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dc3b3c5e0678a5b71728cea8961925e6c0fb44a59340aa2d77d4ea92a24cc7d6
size 316763

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6dbbb518a86c546f188134c1d369762664f188dd6b9a38ec13963b6187cb4b25
size 1456648

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2d7951418e5875da7c7ed8dea482dbf1cbe81a42b47d255db7f1b6e11c16a193
size 1876507

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:80cd11f5be75012cfdf953569e409a355826ca23af35feba41aac78f0e3d35d8
size 1874857

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e605bb18426ea657b9352ecca51f0b55daac904b15dba3afdcffc412a445548a
size 1941423

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c026e8723922a6c56ab8e28f99a29805c53627ff5a659971590c95d89d7ac6bd
size 1940845

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fffa285edd2c5474e16475cafc67d2519e000b74178ce1a0f8d88229827cfabf
size 1937116

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1db7a2f831d83e75e42dfe4f0547e9ed1f171152f45103e8f250d2b52ee3a8e1
size 1937776

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:00c70e7e77b98e4e72d0dde82482066096ebd502d25cccfada9cb87de332ecac
size 1941844

View File

@@ -1,25 +1,190 @@
// This is a basic Flutter integration test.
//
// Since integration tests run in a full Flutter application, they can interact
// with the host side of a plugin implementation, unlike Dart unit tests.
//
// For more information about Flutter integration tests, please see
// https://docs.flutter.dev/cookbook/testing/integration/introduction
import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:polyvox_filament/polyvox_filament.dart';
import 'package:flutter_filament/widgets/filament_widget.dart';
import '../lib/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized()
as IntegrationTestWidgetsFlutterBinding;
testWidgets('getPlatformVersion test', (WidgetTester tester) async {
final PolyvoxFilament plugin = PolyvoxFilament();
final String? version = await plugin.getPlatformVersion();
// The version string depends on the host platform running the test, so
// just assert that some non-empty string is returned.
expect(version?.isNotEmpty, true);
late String platformIdentifier;
if (Platform.isIOS) {
platformIdentifier = "ios";
} else if (Platform.isAndroid) {
platformIdentifier = "android";
} else if (Platform.isMacOS) {
platformIdentifier = "macos";
} else if (Platform.isWindows) {
platformIdentifier = "windows";
} else if (Platform.isLinux) {
platformIdentifier = "linux";
} else {
throw Exception("Unexpected platform");
}
int _counter = 0;
Future _snapshot(WidgetTester tester, String label, [int seconds = 0]) async {
await tester.pumpAndSettle(Duration(milliseconds: 16));
for (int i = 0; i < seconds; i++) {
await Future.delayed(Duration(seconds: 1));
await tester.pumpAndSettle(Duration(milliseconds: 16));
}
await tester.pumpAndSettle(Duration(milliseconds: 16));
var screenshotPath = '$platformIdentifier/${_counter}_$label';
if (Platform.isIOS) {
// this is currently hanging on Android
// see https://github.com/flutter/flutter/issues/127306
// it is also not yet implemented on Windows or MacOS
await binding.convertFlutterSurfaceToImage();
final bytes = await binding.takeScreenshot(screenshotPath);
}
_counter++;
}
Future tap(WidgetTester tester, String label, [int seconds = 0]) async {
var target = find.text(label, skipOffstage: false);
if (!target.hasFound) {
print("Couldn't find target, waiting 100ms");
await tester.pump(const Duration(milliseconds: 100));
target = find.text(label);
}
await tester.tap(target.first);
await _snapshot(tester, label.replaceAll(RegExp("[ -:]"), ""), seconds);
}
Future<void> pumpUntilFound(
WidgetTester tester,
Finder finder, {
Duration timeout = const Duration(seconds: 30),
}) async {
bool timerDone = false;
final timer = Timer(
timeout, () => throw TimeoutException("Pump until has timed out"));
while (timerDone != true) {
await tester.pump();
final found = tester.any(finder);
if (found) {
timerDone = true;
}
}
timer.cancel();
}
testWidgets('test', (WidgetTester tester) async {
app.main();
await pumpUntilFound(tester, find.byType(app.ExampleWidget));
await tester.pumpAndSettle();
await _snapshot(tester, "fresh");
await tap(tester, "Controller / Viewer");
await tap(tester, "Create FilamentController (default ubershader)");
await tap(tester, "Controller / Viewer");
await tap(tester, "Create FilamentViewer",
4); // on older devices this may take a while, so let's insert a length delay
await tap(tester, "Scene");
await tap(tester, "Rendering");
await tap(tester, "Set continuous rendering to true");
await tap(tester, "Scene");
await tap(tester, "Assets");
await tap(tester, "Shapes");
await tap(tester, "Load GLB");
await tester.pump();
await tap(tester, "Scene");
await tap(tester, "Assets");
await tap(tester, "Load skybox", 1);
await tap(tester, "Scene");
await tap(tester, "Assets");
await tap(tester, "Load IBL", 1);
final Offset pointerLocation =
tester.getCenter(find.byType(FilamentWidget));
TestPointer testPointer = TestPointer(1, PointerDeviceKind.mouse);
// scroll/zoom
testPointer.hover(pointerLocation);
await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 1.0)));
await tester.pumpAndSettle();
await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 1.0)));
await tester.pumpAndSettle();
await _snapshot(tester, "zoomin");
// rotate
testPointer =
TestPointer(1, PointerDeviceKind.mouse, null, kTertiaryButton);
testPointer.hover(pointerLocation);
await tester.sendEventToBinding(testPointer.down(pointerLocation));
await tester.pumpAndSettle();
await tester.sendEventToBinding(
testPointer.move(pointerLocation + Offset(10.0, 10.0)));
await tester.pumpAndSettle();
await tester.sendEventToBinding(
testPointer.move(pointerLocation + Offset(20.0, 20.0)));
await tester.pumpAndSettle();
await tester.sendEventToBinding(testPointer.up());
await _snapshot(tester, "rotate", 2);
// pan
testPointer = TestPointer(1, PointerDeviceKind.mouse, null, kPrimaryButton);
testPointer.hover(pointerLocation);
await tester.sendEventToBinding(testPointer.down(pointerLocation));
await tester
.sendEventToBinding(testPointer.move(pointerLocation + Offset(0, 1.0)));
for (int i = 0; i < 60; i++) {
await tester.sendEventToBinding(testPointer
.move(pointerLocation + Offset(i.toDouble() * 2, i.toDouble() * 2)));
await tester.pumpAndSettle();
}
await tester.sendEventToBinding(testPointer.up());
await tester.pumpAndSettle();
await _snapshot(tester, "pan");
await tap(tester, "Scene");
await tap(tester, "Assets");
await tap(tester, "Shapes");
await tap(tester, "Transform to unit cube");
await tap(tester, "Scene");
await tap(tester, "Assets");
await tap(tester, "Shapes");
await tap(tester, "Set position to 1, 1, -1");
await tap(tester, "Scene");
await tap(tester, "Camera");
await tap(tester, "Disable frustum culling");
await tap(tester, "Scene");
await tap(tester, "Rendering");
await tap(tester, "Set tone mapping to linear");
await tap(tester, "Scene");
await tap(tester, "Camera");
await tap(tester, 'Set to first camera in last added asset');
await tap(tester, "Move to last added asset");
await tap(tester, "Move to 1, 1, -1");
await tap(tester, 'Toggle viewport size', 1);
await tap(tester, 'Toggle viewport size', 1);
await tap(tester, 'Toggle viewport size', 1);
});
}

View File

@@ -1,21 +1,40 @@
PODS:
- Flutter (1.0.0)
- polyvox_filament (0.0.1):
- flutter_filament (0.0.1):
- Flutter
- integration_test (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.1.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- polyvox_filament (from `.symlinks/plugins/polyvox_filament/ios`)
- flutter_filament (from `.symlinks/plugins/flutter_filament/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
polyvox_filament:
:path: ".symlinks/plugins/polyvox_filament/ios"
flutter_filament:
:path: ".symlinks/plugins/flutter_filament/ios"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
polyvox_filament: 99047b2e0d56e073f5db603dd6152a1598c2a345
flutter_filament: 9d744e795935e0fc5308e46a0c5947cb91714848
integration_test: 13825b8a9334a850581300559b8839134b124670
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
PODFILE CHECKSUM: 7adbc9d59f05e1b01f554ea99b6c79e97f2214a2

View File

@@ -138,6 +138,7 @@
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
F9FAB8A67CF505858CCDA424 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -249,6 +250,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
F9FAB8A67CF505858CCDA424 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -343,6 +361,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = TM2B4SJXNJ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -354,6 +373,8 @@
OTHER_CFLAGS = "-fvisibility=default";
PRODUCT_BUNDLE_IDENTIFIER = app.polyvox.example;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
STRIP_STYLE = "non-global";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -479,6 +500,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = TM2B4SJXNJ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -490,6 +512,8 @@
OTHER_CFLAGS = "-fvisibility=default";
PRODUCT_BUNDLE_IDENTIFIER = app.polyvox.example;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
STRIP_STYLE = "non-global";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -505,6 +529,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = TM2B4SJXNJ;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -516,6 +541,8 @@
OTHER_CFLAGS = "-fvisibility=default";
PRODUCT_BUNDLE_IDENTIFIER = app.polyvox.example;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
STRIP_STYLE = "non-global";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";

View File

@@ -2,7 +2,7 @@ import Flutter
import UIKit
import XCTest
@testable import polyvox_filament
@testable import flutter_filament
// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
@@ -11,7 +11,7 @@ import XCTest
class RunnerTests: XCTestCase {
func testGetPlatformVersion() {
let plugin = PolyvoxFilamentPlugin()
let plugin = FlutterFilamentPlugin()
let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])

View File

@@ -0,0 +1,65 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/filament_controller.dart';
class CameraMatrixOverlay extends StatefulWidget {
final FilamentController controller;
const CameraMatrixOverlay({super.key, required this.controller});
@override
State<StatefulWidget> createState() => _CameraMatrixOverlayState();
}
class _CameraMatrixOverlayState extends State<CameraMatrixOverlay> {
Timer? _cameraTimer;
String? _cameraPosition;
String? _cameraRotation;
void _updateTimer() {
_cameraTimer?.cancel();
if (widget.controller.hasViewer.value) {
_cameraTimer =
Timer.periodic(const Duration(milliseconds: 50), (timer) async {
var cameraPosition = await widget.controller.getCameraPosition();
var cameraRotation = await widget.controller.getCameraRotation();
_cameraPosition =
"${cameraPosition.storage.map((v) => v.toStringAsFixed(2))}";
_cameraRotation =
"${cameraRotation.storage.map((v) => v.toStringAsFixed(2))}";
setState(() {});
});
}
}
@override
void initState() {
super.initState();
_updateTimer();
widget.controller.hasViewer.addListener(_updateTimer);
}
@override
void dispose() {
super.dispose();
widget.controller.hasViewer.removeListener(_updateTimer);
_cameraTimer?.cancel();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.circular(29)),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Text("Camera position : $_cameraPosition $_cameraRotation",
style: const TextStyle(color: Colors.white, fontSize: 12)));
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament/widgets/filament_gesture_detector.dart';
import 'package:flutter_filament/widgets/filament_widget.dart';
class ExampleViewport extends StatelessWidget {
final FilamentController? controller;
final EdgeInsets padding;
const ExampleViewport(
{super.key, required this.controller, required this.padding});
@override
Widget build(BuildContext context) {
return controller != null
? Padding(
padding: padding,
child: FilamentGestureDetector(
showControlOverlay: true,
controller: controller!,
child: FilamentWidget(
controller: controller!,
)))
: Container();
}
}

View File

@@ -1,19 +1,20 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_filament/filament_controller_ffi.dart';
import 'package:flutter_filament_example/camera_matrix_overlay.dart';
import 'package:flutter_filament_example/menus/controller_menu.dart';
import 'package:flutter_filament_example/example_viewport.dart';
import 'package:flutter_filament_example/picker_result_widget.dart';
import 'package:flutter_filament_example/menus/scene_menu.dart';
import 'package:polyvox_filament/filament_controller.dart';
import 'package:polyvox_filament/animations/bone_animation_data.dart';
import 'package:polyvox_filament/filament_controller_ffi.dart';
import 'package:polyvox_filament/animations/animation_builder.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:path_provider/path_provider.dart';
import 'package:polyvox_filament/widgets/filament_gesture_detector.dart';
import 'package:polyvox_filament/widgets/filament_widget.dart';
const loadDefaultScene = bool.hasEnvironment('--load-default-scene');
void main() {
runApp(const MyApp());
void main() async {
print(loadDefaultScene);
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@@ -27,505 +28,144 @@ class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
// showPerformanceOverlay: true,
color: Colors.white,
home: Scaffold(backgroundColor: Colors.white, body: ExampleWidget()));
home: const Scaffold(body: ExampleWidget()));
}
}
class ExampleWidget extends StatefulWidget {
const ExampleWidget({super.key});
@override
State<StatefulWidget> createState() {
return _ExampleWidgetState();
return ExampleWidgetState();
}
}
class _ExampleWidgetState extends State<ExampleWidget> {
FilamentControllerFFI? _filamentController;
enum MenuType { controller, assets, camera, misc }
FilamentEntity? _shapes;
FilamentEntity? _flightHelmet;
List<String>? _animations;
FilamentEntity? _light;
class ExampleWidgetState extends State<ExampleWidget> {
FilamentController? _filamentController;
late StreamSubscription _pickResultListener;
String? picked;
EdgeInsets _viewportMargin = EdgeInsets.zero;
final weights = List.filled(255, 0.0);
// these are all the options that can be set via the menu
// we store them here
static bool rendering = false;
static int framerate = 60;
static bool postProcessing = true;
static bool frustumCulling = true;
static ManipulatorMode cameraManipulatorMode = ManipulatorMode.ORBIT;
bool _loop = false;
bool _vertical = false;
bool _rendering = false;
int _framerate = 60;
bool _postProcessing = true;
bool _active = false;
static double zoomSpeed = 0.01;
static double orbitSpeedX = 0.01;
static double orbitSpeedY = 0.01;
bool _coneHidden = false;
bool _frustumCulling = true;
static FilamentEntity? last;
static bool hasSkybox = false;
static bool coneHidden = false;
static FilamentEntity? shapes;
static FilamentEntity? flightHelmet;
static FilamentEntity? buster;
static List<String>? animations;
static FilamentEntity? directionalLight;
static bool loop = false;
late StreamSubscription _listener;
@override
void initState() {
getApplicationSupportDirectory().then((dir) {
print(dir);
});
super.initState();
if (loadDefaultScene) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
setState(() {
_filamentController = FilamentControllerFFI();
});
await Future.delayed(const Duration(milliseconds: 100));
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await _filamentController!.createViewer();
await _filamentController!
.loadSkybox("assets/default_env/default_env_skybox.ktx");
await _filamentController!.setRendering(true);
await _filamentController!.loadGlb("assets/shapes/shapes.glb");
});
});
}
}
@override
void dispose() {
super.dispose();
_pickResultListener.cancel();
}
Widget _item(void Function() onTap, String text) {
return GestureDetector(
onTap: () {
setState(() {
onTap();
});
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
child: Text(text)));
}
void _createController({String? uberArchivePath}) {
_filamentController =
FilamentControllerFFI(uberArchivePath: uberArchivePath);
_filamentController!.pickResult.listen((entityId) {
setState(() {
picked = _filamentController!.getNameForEntity(entityId);
});
});
_listener.cancel();
}
@override
Widget build(BuildContext context) {
var children = <Widget>[];
if (_filamentController == null) {
children.addAll([
_item(() {
_createController();
}, "create viewer (default ubershader)"),
_item(() {
_createController(
uberArchivePath: Platform.isWindows
? "assets/lit_opaque_32.uberz"
: "assets/lit_opaque_43.uberz");
}, "create viewer (custom ubershader - lit opaque only)"),
]);
} else {
children.addAll([
_item(() {
_filamentController!.destroy();
_filamentController = null;
}, "destroy viewer/texture")
]);
}
if (_filamentController != null) {
children.addAll([
_item(() {
_filamentController!.render();
}, "render"),
_item(() {
setState(() {
_rendering = !_rendering;
_filamentController!.setRendering(_rendering);
});
}, "Rendering: $_rendering "),
_item(() {
setState(() {
_framerate = _framerate == 60 ? 30 : 60;
_filamentController!.setFrameRate(_framerate);
});
}, "$_framerate fps"),
_item(() {
_filamentController!.setBackgroundColor(Color(0xFF73C9FA));
}, "set background color"),
_item(() {
_filamentController!.setBackgroundImage('assets/background.ktx');
}, "load background image"),
_item(() {
_filamentController!
.setBackgroundImage('assets/background.ktx', fillHeight: true);
}, "load background image (fill height)"),
_item(() {
_filamentController!
.loadSkybox('assets/default_env/default_env_skybox.ktx');
}, 'load skybox'),
_item(() {
_filamentController!
.loadIbl('assets/default_env/default_env_ibl.ktx');
}, 'load IBL'),
_item(() {
setState(() {
_postProcessing = !_postProcessing;
});
_filamentController!.setPostProcessing(_postProcessing);
}, "${_postProcessing ? "Disable" : "Enable"} postprocessing"),
_item(
() {
_filamentController!.removeSkybox();
},
'remove skybox',
),
_item(() async {
_shapes =
await _filamentController!.loadGlb('assets/shapes/shapes.glb');
_animations = await _filamentController!.getAnimationNames(_shapes!);
setState(() {});
}, 'load shapes GLB'),
_item(() async {
_animations = await _filamentController!.setCamera(_shapes!, null);
setState(() {});
}, 'set camera to first camera in shapes GLB'),
_item(() async {
if (_coneHidden) {
_filamentController!.reveal(_shapes!, "Cone");
} else {
_filamentController!.hide(_shapes!, "Cone");
}
setState(() {
_coneHidden = !_coneHidden;
});
}, _coneHidden ? 'show cone' : 'hide cone'),
_item(() async {
if (_shapes != null) {
_filamentController!.removeAsset(_shapes!);
}
_shapes = await _filamentController!
.loadGltf('assets/shapes/shapes.gltf', 'assets/shapes');
}, 'load shapes GLTF'),
_item(() async {
_filamentController!.transformToUnitCube(_shapes!);
}, 'transform to unit cube'),
_item(() async {
_filamentController!.setPosition(_shapes!, 1.0, 1.0, -1.0);
}, 'set shapes position to 1, 1, -1'),
_item(() async {
_filamentController!.setPosition(_shapes!, 1.0, 1.0, -1.0);
}, 'move camera to shapes position'),
_item(() async {
var frameData = Float32List.fromList(
List<double>.generate(120, (i) => i / 120).expand((x) {
var vals = List<double>.filled(7, x);
vals[3] = 1.0;
// vals[4] = 0;
vals[5] = 0;
vals[6] = 0;
return vals;
}).toList());
_filamentController!.setBoneAnimation(
_shapes!,
BoneAnimationData(
"Bone.001", ["Cube.001"], frameData, 1000.0 / 60.0));
// ,
// "Bone.001",
// "Cube.001",
// BoneTransform([Vec3(x: 0, y: 0.0, z: 0.0)],
// [Quaternion(x: 1, y: 1, z: 1, w: 1)]));
}, 'construct bone animation'),
_item(() async {
_filamentController!.removeAsset(_shapes!);
_shapes = null;
}, 'remove shapes'),
_item(() async {
_filamentController!.clearAssets();
_shapes = null;
}, 'clear all assets'),
_item(() async {
var names = await _filamentController!
.getMorphTargetNames(_shapes!, "Cylinder");
await showDialog(
context: context,
builder: (ctx) {
return Container(
height: 100,
width: 100,
color: Colors.white,
child: Text(names.join(",")));
});
}, "show morph target names for Cylinder"),
_item(() {
_filamentController!
.setMorphTargetWeights(_shapes!, "Cylinder", List.filled(4, 1.0));
}, "set Cylinder morph weights to 1"),
_item(() {
_filamentController!
.setMorphTargetWeights(_shapes!, "Cylinder", List.filled(4, 0.0));
}, "set Cylinder morph weights to 0.0"),
_item(() async {
var morphs = await _filamentController!
.getMorphTargetNames(_shapes!, "Cylinder");
final animation = AnimationBuilder(
availableMorphs: morphs, framerate: 30, meshName: "Cylinder")
.setDuration(4)
.setMorphTargets(["Key 1", "Key 2"])
.interpolateMorphWeights(0, 4, 0, 1)
.build();
_filamentController!.setMorphAnimationData(_shapes!, animation);
}, "animate cylinder morph weights #1 and #2"),
_item(() async {
var morphs = await _filamentController!
.getMorphTargetNames(_shapes!, "Cylinder");
final animation = AnimationBuilder(
availableMorphs: morphs, framerate: 30, meshName: "Cylinder")
.setDuration(4)
.setMorphTargets(["Key 3", "Key 4"])
.interpolateMorphWeights(0, 4, 0, 1)
.build();
_filamentController!.setMorphAnimationData(_shapes!, animation);
}, "animate cylinder morph weights #3 and #4"),
_item(() async {
var morphs =
await _filamentController!.getMorphTargetNames(_shapes!, "Cube");
final animation = AnimationBuilder(
availableMorphs: morphs, framerate: 30, meshName: "Cube")
.setDuration(4)
.setMorphTargets(["Key 1", "Key 2"])
.interpolateMorphWeights(0, 4, 0, 1)
.build();
_filamentController!.setMorphAnimationData(_shapes!, animation);
}, "animate shapes morph weights #1 and #2"),
_item(() {
_filamentController!
.setMaterialColor(_shapes!, "Cone", 0, Colors.purple);
}, "set cone material color to purple"),
_item(() {
_loop = !_loop;
setState(() {});
}, "toggle animation looping ${_loop ? "OFF" : "ON"}")
]);
if (_animations != null) {
children.addAll(_animations!.map((a) => _item(() {
_filamentController!.playAnimation(
_shapes!, _animations!.indexOf(a),
replaceActive: true, crossfade: 0.5, loop: _loop);
}, "play animation ${_animations!.indexOf(a)} (replace/fade)")));
children.addAll(_animations!.map((a) => _item(() {
_filamentController!.playAnimation(
_shapes!, _animations!.indexOf(a),
replaceActive: false, loop: _loop);
}, "play animation ${_animations!.indexOf(a)} (noreplace)")));
}
children.add(_item(() {
_filamentController!.setToneMapping(ToneMapper.LINEAR);
}, "Set tone mapping to linear"));
children.add(_item(() {
_filamentController!.moveCameraToAsset(_shapes!);
}, "Move camera to asset"));
children.add(_item(() {
setState(() {
_frustumCulling = !_frustumCulling;
});
_filamentController!.setViewFrustumCulling(_frustumCulling);
}, "${_frustumCulling ? "Disable" : "Enable"} frustum culling"));
}
return Stack(children: [
_filamentController != null
? Positioned.fill(
child: FilamentGestureDetector(
showControlOverlay: true,
controller: _filamentController!,
child: FilamentWidget(
controller: _filamentController!,
)))
: Container(),
Positioned(
right: 50,
top: 50,
child: Text(picked ?? "",
style: TextStyle(color: Colors.green, fontSize: 24))),
Positioned(
bottom: 0,
left: 0,
right: 0,
height: 200,
Positioned.fill(
child: ExampleViewport(
controller: _filamentController,
padding: _viewportMargin,
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: const EdgeInsets.only(bottom: 30),
height: 100,
color: Colors.white,
child: SingleChildScrollView(
child: Wrap(children: children
// _item(24 () async { 'rotate by pi around Y axis'),
// _item(5 () async { 'load flight helmet'),
// _item(7 () async { 'set all weights to 1'),
// _item(8 () async { 'set all weights to 0'),
// _item(9 () async { 'play all animations'),
// _item(34 () async { 'play animation 0'),
// _item(34 () async { 'play animation 0 (noreplace)'),
// _item(35 () async { 'play animation 1'),
// _item(34 () async { 'play animation 0 (noreplace)'),
// _item(36 () async { 'play animation 2'),
// _item(34 () async { 'play animation 0 (noreplace)'),
// _item(36 () async { 'play animation 3'),
// _item(34 () async { 'play animation 3 (noreplace)'),
// _item(37 () async { 'stop animation 0'),
// _item(14 () async { 'set camera'),
// _item(15 () async { 'animate weights'),
// _item(16 () async { 'get target names'),
// _item(17 () async { 'get animation names'),
// _item(18 () async { 'pan left'),
// _item(19 () async { 'pan right'),
// _item(25 () async {
// Text(_vertical ? 'set horizontal' : 'set vertical')),
// _item(26 () async { 'set camera pos to 0,0,3'),
// _item(27 () async { 'toggle framerate'),
// _item(28 () async { 'set bg image pos'),
// _item(29 () async { 'add light'),
// _item(30 () async { 'remove light'),
// _item(31 () async { 'clear all lights'),
// _item(32 () async { 'set camera model matrix'),
))))
child: Row(crossAxisAlignment: CrossAxisAlignment.end, children: [
ControllerMenu(
controller: _filamentController,
onControllerDestroyed: () {},
onControllerCreated: (controller) {
setState(() {
_filamentController = controller;
_listener = _filamentController!.onLoad
.listen((FilamentEntity entity) {
print("Set last to $entity");
last = entity;
if (mounted) {
setState(() {});
}
print(_filamentController!.getNameForEntity(entity) ??
"NAME NOT FOUND");
});
});
}),
SceneMenu(
controller: _filamentController,
),
Expanded(child: Container()),
TextButton(
child: const Text("Toggle viewport size"),
onPressed: () {
setState(() {
_viewportMargin = (_viewportMargin == EdgeInsets.zero)
? const EdgeInsets.all(30)
: EdgeInsets.zero;
});
},
)
]))),
_filamentController == null
? Container()
: Padding(
padding: const EdgeInsets.only(top: 40, left: 20, right: 20),
child: CameraMatrixOverlay(controller: _filamentController!),
),
_filamentController == null
? Container()
: Align(
alignment: Alignment.topRight,
child: PickerResultWidget(controller: _filamentController!),
)
]);
}
}
// case -1:
// break;
// case -2:
// _filamentController!.render();
// break;
// case -4:
// setState(() {
// _rendering = !_rendering;
// _filamentController!.setRendering(_rendering);
// });
// break;
// case -5:
// setState(() {
// _framerate = _framerate == 60 ? 30 : 60;
// _filamentController!.setFrameRate(_framerate);
// });
// break;
// case -6:
// _filamentController!.setBackgroundColor(Color(0xFF73C9FA));
// break;
// case 5:
// _flightHelmet ??= await _filamentController!.loadGltf(
// 'assets/FlightHelmet/FlightHelmet.gltf', 'assets/FlightHelmet');
// break;
// case 11:
// setState(() {
// _loop = !_loop;
// });
// break;
// case 14:
// _filamentController!.setCamera(_shapes!, "Camera_Orientation");
// break;
// case 15:
// break;
// case 17:
// var animationNames =
// await _filamentController!.getAnimationNames(_shapes!);
// await showDialog(
// context: context,
// builder: (ctx) {
// return Container(
// height: 100,
// width: 100,
// color: Colors.white,
// child: Text(animationNames.join(",")));
// });
// break;
// case 18:
// _filamentController!.panStart(1, 1);
// _filamentController!.panUpdate(1, 2);
// _filamentController!.panEnd();
// break;
// case 19:
// _filamentController!.panStart(1, 1);
// _filamentController!.panUpdate(0, 0);
// _filamentController!.panEnd();
// break;
// case 20:
// _filamentController!.clearAssets();
// break;
// case 21:
// break;
// case 22:
// break;
// case 23:
// break;
// case 24:
// _filamentController!.setRotation(_shapes!, pi / 2, 0.0, 1.0, 0.0);
// break;
// case 25:
// setState(() {
// _vertical = !_vertical;
// });
// break;
// case 26:
// _filamentController!.setCameraPosition(0, 0, 3);
// _filamentController!.setCameraRotation(0, 0, 1, 0);
// break;
// case 27:
// _framerate = _framerate == 60 ? 30 : 60;
// _filamentController!.setFrameRate(_framerate);
// break;
// case 28:
// _filamentController!.setBackgroundImagePosition(25, 25);
// break;
// case 29:
// _light = await _filamentController!.addLight(
// 1, 6500, 15000000, 0, 1, 0, 0, -1, 0, true);
// break;
// case 30:
// if (_light != null) {
// _filamentController!.removeLight(_light!);
// _light = null;
// }
// break;
// case 31:
// _filamentController!.clearLights();
// break;
// case 32:
// // break;
// break;
// case 33:
// break;
// case 34:
// var duration =
// await _filamentController!.getAnimationDuration(_shapes!, 0);
// _filamentController!.playAnimation(_shapes!, 0,
// loop: false, crossfade: 0.5);
// await Future.delayed(
// Duration(milliseconds: (duration * 1000.0).toInt()));
// print("animation complete");
// // showDialog(
// // context: context,
// // builder: (context) {
// // return Container(
// // width: 100,
// // height: 100,
// // color: Colors.white,
// // child: "animation complete!");
// // });
// break;
// case 35:
// _filamentController!.playAnimation(_shapes!, 1,
// loop: false, crossfade: 0.5);
// break;
// case 36:
// _filamentController!.playAnimation(_shapes!, 2,
// loop: false, crossfade: 0.5);
// break;
// case 37:
// _filamentController!.stopAnimation(_shapes!, 0);
// break;

View File

@@ -0,0 +1,309 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament_example/main.dart';
import 'package:permission_handler/permission_handler.dart';
class AssetSubmenu extends StatefulWidget {
final FilamentController controller;
const AssetSubmenu({super.key, required this.controller});
@override
State<StatefulWidget> createState() => _AssetSubmenuState();
}
class _AssetSubmenuState extends State<AssetSubmenu> {
@override
void initState() {
super.initState();
}
Widget _shapesSubmenu() {
var children = [
MenuItemButton(
onPressed: () async {
if (ExampleWidgetState.shapes == null) {
ExampleWidgetState.shapes =
await widget.controller.loadGlb('assets/shapes/shapes.glb');
ExampleWidgetState.animations = await widget.controller
.getAnimationNames(ExampleWidgetState.shapes!);
} else {
await widget.controller.removeAsset(ExampleWidgetState.shapes!);
ExampleWidgetState.shapes = null;
ExampleWidgetState.animations = null;
}
},
child: const Text('Load GLB')),
MenuItemButton(
onPressed: ExampleWidgetState.shapes != null
? null
: () async {
if (ExampleWidgetState.shapes != null) {
widget.controller.removeAsset(ExampleWidgetState.shapes!);
}
ExampleWidgetState.shapes = await widget.controller
.loadGltf('assets/shapes/shapes.gltf', 'assets/shapes');
},
child: const Text('Load GLTF')),
MenuItemButton(
onPressed: ExampleWidgetState.shapes == null
? null
: () async {
await widget.controller
.transformToUnitCube(ExampleWidgetState.shapes!);
},
child: const Text('Transform to unit cube')),
MenuItemButton(
onPressed: () async {
var names = await widget.controller
.getMorphTargetNames(ExampleWidgetState.shapes!, "Cylinder");
await showDialog(
context: context,
builder: (ctx) {
return Container(
height: 100,
width: 100,
color: Colors.white,
child: Text(names.join(",")));
});
},
child: const Text("Show morph target names for Cylinder")),
MenuItemButton(
onPressed: () async {
widget.controller.setMorphTargetWeights(
ExampleWidgetState.shapes!, "Cylinder", List.filled(4, 1.0));
},
child: const Text("set Cylinder morph weights to 1")),
MenuItemButton(
onPressed: () async {
widget.controller.setMorphTargetWeights(
ExampleWidgetState.shapes!, "Cylinder", List.filled(4, 0.0));
},
child: const Text("Set Cylinder morph weights to 0")),
MenuItemButton(
onPressed: () async {
widget.controller
.setPosition(ExampleWidgetState.shapes!, 1.0, 1.0, -1.0);
},
child: const Text('Set position to 1, 1, -1'),
),
MenuItemButton(
onPressed: () async {
if (ExampleWidgetState.coneHidden) {
widget.controller.reveal(ExampleWidgetState.shapes!, "Cone");
} else {
widget.controller.hide(ExampleWidgetState.shapes!, "Cone");
}
ExampleWidgetState.coneHidden = !ExampleWidgetState.coneHidden;
},
child:
Text(ExampleWidgetState.coneHidden ? 'show cone' : 'hide cone')),
MenuItemButton(
onPressed: ExampleWidgetState.shapes == null
? null
: () async {
widget.controller.setMaterialColor(
ExampleWidgetState.shapes!, "Cone", 0, Colors.purple);
},
child: const Text("Set cone material color to purple")),
MenuItemButton(
onPressed: () async {
ExampleWidgetState.loop = !ExampleWidgetState.loop;
},
child: Text(
"Toggle animation looping ${ExampleWidgetState.loop ? "OFF" : "ON"}"))
];
if (ExampleWidgetState.animations != null) {
children.addAll(ExampleWidgetState.animations!.map((a) => MenuItemButton(
onPressed: () {
widget.controller.playAnimation(ExampleWidgetState.shapes!,
ExampleWidgetState.animations!.indexOf(a),
replaceActive: true,
crossfade: 0.5,
loop: ExampleWidgetState.loop);
},
child: Text(
"play animation ${ExampleWidgetState.animations!.indexOf(a)} (replace/fade)"))));
children.addAll(ExampleWidgetState.animations!.map((a) => MenuItemButton(
onPressed: () {
widget.controller.playAnimation(ExampleWidgetState.shapes!,
ExampleWidgetState.animations!.indexOf(a),
replaceActive: false, loop: ExampleWidgetState.loop);
},
child: Text(
"Play animation ${ExampleWidgetState.animations!.indexOf(a)} (noreplace)"))));
}
return SubmenuButton(menuChildren: children, child: const Text("Shapes"));
}
@override
Widget build(BuildContext context) {
return SubmenuButton(
menuChildren: [
_shapesSubmenu(),
MenuItemButton(
onPressed: () async {
ExampleWidgetState.directionalLight = await widget.controller
.addLight(1, 6500, 150000, 0, 1, 0, 0, -1, 0, true);
},
child: const Text("Add directional light"),
),
MenuItemButton(
onPressed: () async {
await widget.controller.clearLights();
},
child: const Text("Clear lights"),
),
MenuItemButton(
onPressed: () async {
if (ExampleWidgetState.buster == null) {
ExampleWidgetState.buster = await widget.controller.loadGltf(
"assets/BusterDrone/scene.gltf", "assets/BusterDrone",
force: true);
await widget.controller
.playAnimation(ExampleWidgetState.buster!, 0, loop: true);
ExampleWidgetState.animations = await widget.controller
.getAnimationNames(ExampleWidgetState.shapes!);
} else {
await widget.controller.removeAsset(ExampleWidgetState.buster!);
ExampleWidgetState.buster = null;
}
},
child: Text(ExampleWidgetState.buster == null
? 'Load buster'
: 'Remove buster')),
MenuItemButton(
onPressed: () async {
if (ExampleWidgetState.flightHelmet == null) {
ExampleWidgetState.flightHelmet ??= await widget.controller
.loadGltf('assets/FlightHelmet/FlightHelmet.gltf',
'assets/FlightHelmet',
force: true);
} else {
await widget.controller
.removeAsset(ExampleWidgetState.flightHelmet!);
ExampleWidgetState.flightHelmet = null;
}
},
child: Text(ExampleWidgetState.flightHelmet == null
? 'Load flight helmet'
: 'Remove flight helmet')),
MenuItemButton(
onPressed: () {
widget.controller.setBackgroundColor(const Color(0xFF73C9FA));
},
child: const Text("Set background color")),
MenuItemButton(
onPressed: () {
widget.controller.setBackgroundImage('assets/background.ktx');
},
child: const Text("Load background image")),
MenuItemButton(
onPressed: () {
widget.controller.setBackgroundImage('assets/background.ktx',
fillHeight: true);
},
child: const Text("Load background image (fill height)")),
MenuItemButton(
onPressed: () {
if (ExampleWidgetState.hasSkybox) {
widget.controller.removeSkybox();
} else {
widget.controller
.loadSkybox('assets/default_env/default_env_skybox.ktx');
}
ExampleWidgetState.hasSkybox = !ExampleWidgetState.hasSkybox;
},
child: Text(ExampleWidgetState.hasSkybox
? 'Remove skybox'
: 'Load skybox')),
MenuItemButton(
onPressed: () {
widget.controller
.loadIbl('assets/default_env/default_env_ibl.ktx');
},
child: const Text('Load IBL')),
MenuItemButton(
onPressed: () async {
await Permission.microphone.request();
},
child: const Text("Request permissions (tests inactive->resume)")),
MenuItemButton(
onPressed: () async {
await widget.controller.clearAssets();
ExampleWidgetState.flightHelmet = null;
ExampleWidgetState.buster = null;
ExampleWidgetState.shapes = null;
},
child: const Text('Clear assets')),
],
child: const Text("Assets"),
);
}
}
// _item(() async {
// var frameData = Float32List.fromList(
// List<double>.generate(120, (i) => i / 120).expand((x) {
// var vals = List<double>.filled(7, x);
// vals[3] = 1.0;
// // vals[4] = 0;
// vals[5] = 0;
// vals[6] = 0;
// return vals;
// }).toList());
// widget.controller!.setBoneAnimation(
// _shapes!,
// BoneAnimationData(
// "Bone.001", ["Cube.001"], frameData, 1000.0 / 60.0));
// // ,
// // "Bone.001",
// // "Cube.001",
// // BoneTransform([Vec3(x: 0, y: 0.0, z: 0.0)],
// // [Quaternion(x: 1, y: 1, z: 1, w: 1)]));
// }, 'construct bone animation'),
// _item(() async {
// var morphs = await widget.controller!
// .getMorphTargetNames(_shapes!, "Cylinder");
// final animation = AnimationBuilder(
// availableMorphs: morphs,
// framerate: 30,
// meshName: "Cylinder")
// .setDuration(4)
// .setMorphTargets(["Key 1", "Key 2"])
// .interpolateMorphWeights(0, 4, 0, 1)
// .build();
// widget.controller!.setMorphAnimationData(_shapes!, animation);
// }, "animate cylinder morph weights #1 and #2"),
// _item(() async {
// var morphs = await widget.controller!
// .getMorphTargetNames(_shapes!, "Cylinder");
// final animation = AnimationBuilder(
// availableMorphs: morphs,
// framerate: 30,
// meshName: "Cylinder")
// .setDuration(4)
// .setMorphTargets(["Key 3", "Key 4"])
// .interpolateMorphWeights(0, 4, 0, 1)
// .build();
// widget.controller!.setMorphAnimationData(_shapes!, animation);
// }, "animate cylinder morph weights #3 and #4"),
// _item(() async {
// var morphs = await widget.controller!
// .getMorphTargetNames(_shapes!, "Cube");
// final animation = AnimationBuilder(
// availableMorphs: morphs, framerate: 30, meshName: "Cube")
// .setDuration(4)
// .setMorphTargets(["Key 1", "Key 2"])
// .interpolateMorphWeights(0, 4, 0, 1)
// .build();
// widget.controller!.setMorphAnimationData(_shapes!, animation);
// }, "animate shapes morph weights #1 and #2"),

View File

@@ -0,0 +1,171 @@
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament_example/main.dart';
class CameraSubmenu extends StatefulWidget {
final FilamentController controller;
const CameraSubmenu({super.key, required this.controller});
@override
State<StatefulWidget> createState() => _CameraSubmenuState();
}
class _CameraSubmenuState extends State<CameraSubmenu> {
List<Widget> _cameraMenu() {
return [
MenuItemButton(
onPressed: () async {
widget.controller.setCameraPosition(1.0, 1.0, -1.0);
},
child: const Text('Move to 1, 1, -1'),
),
MenuItemButton(
onPressed: ExampleWidgetState.last == null
? null
: () async {
await widget.controller
.setCamera(ExampleWidgetState.last!, null);
},
child: const Text('Set to first camera in last added asset'),
),
MenuItemButton(
onPressed: ExampleWidgetState.last == null
? null
: () async {
await widget.controller
.moveCameraToAsset(ExampleWidgetState.last!);
},
child: const Text("Move to last added asset"),
),
MenuItemButton(
onPressed: () {
widget.controller.setCameraRotation(pi / 4, 0.0, 1.0, 0.0);
},
child: const Text("Rotate camera 45 degrees around y axis"),
),
MenuItemButton(
onPressed: () {
ExampleWidgetState.frustumCulling =
!ExampleWidgetState.frustumCulling;
widget.controller
.setViewFrustumCulling(ExampleWidgetState.frustumCulling);
},
child: Text(
"${ExampleWidgetState.frustumCulling ? "Disable" : "Enable"} frustum culling"),
),
MenuItemButton(
closeOnActivate: false,
onPressed: () async {
var projMatrix =
await widget.controller.getCameraProjectionMatrix();
await showDialog(
context: context,
builder: (ctx) {
return Center(
child: Container(
height: 100,
width: 300,
color: Colors.white,
child: Text(projMatrix.storage
.map((v) => v.toStringAsFixed(2))
.join(","))));
});
},
child: const Text("Get projection matrix")),
MenuItemButton(
closeOnActivate: false,
onPressed: () async {
var frustum = await widget.controller.getCameraFrustum();
await showDialog(
context: context,
builder: (ctx) {
return Center(
child: Container(
height: 300,
width: 300,
color: Colors.white,
child: Text(frustum.toString())));
});
},
child: const Text("Get frustum")),
SubmenuButton(
menuChildren: ManipulatorMode.values.map((mm) {
return MenuItemButton(
onPressed: () {
ExampleWidgetState.cameraManipulatorMode = mm;
widget.controller.setCameraManipulatorOptions(
mode: ExampleWidgetState.cameraManipulatorMode,
orbitSpeedX: ExampleWidgetState.orbitSpeedX,
orbitSpeedY: ExampleWidgetState.orbitSpeedY,
zoomSpeed: ExampleWidgetState.zoomSpeed);
},
child: Text(
mm.name,
style: TextStyle(
fontWeight: ExampleWidgetState.cameraManipulatorMode == mm
? FontWeight.bold
: FontWeight.normal),
),
);
}).toList(),
child: const Text("Manipulator mode")),
SubmenuButton(
menuChildren: [0.01, 0.1, 1.0, 10.0, 100.0].map((speed) {
return MenuItemButton(
onPressed: () {
ExampleWidgetState.zoomSpeed = speed;
widget.controller.setCameraManipulatorOptions(
mode: ExampleWidgetState.cameraManipulatorMode,
orbitSpeedX: ExampleWidgetState.orbitSpeedX,
orbitSpeedY: ExampleWidgetState.orbitSpeedY,
zoomSpeed: ExampleWidgetState.zoomSpeed);
},
child: Text(
speed.toString(),
style: TextStyle(
fontWeight:
(speed - ExampleWidgetState.zoomSpeed).abs() < 0.0001
? FontWeight.bold
: FontWeight.normal),
),
);
}).toList(),
child: const Text("Zoom speed")),
SubmenuButton(
menuChildren: [0.001, 0.01, 0.1, 1.0].map((speed) {
return MenuItemButton(
onPressed: () {
ExampleWidgetState.orbitSpeedX = speed;
ExampleWidgetState.orbitSpeedY = speed;
widget.controller.setCameraManipulatorOptions(
mode: ExampleWidgetState.cameraManipulatorMode,
orbitSpeedX: ExampleWidgetState.orbitSpeedX,
orbitSpeedY: ExampleWidgetState.orbitSpeedY,
zoomSpeed: ExampleWidgetState.zoomSpeed);
},
child: Text(
speed.toString(),
style: TextStyle(
fontWeight:
(speed - ExampleWidgetState.orbitSpeedX).abs() < 0.0001
? FontWeight.bold
: FontWeight.normal),
),
);
}).toList(),
child: const Text("Orbit speed (X & Y)"))
];
}
@override
Widget build(BuildContext context) {
return SubmenuButton(
menuChildren: _cameraMenu(),
child: const Text("Camera"),
);
}
}

View File

@@ -0,0 +1,117 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament/filament_controller_ffi.dart';
class ControllerMenu extends StatefulWidget {
final FilamentController? controller;
final void Function(FilamentController controller) onControllerCreated;
final void Function() onControllerDestroyed;
ControllerMenu(
{this.controller,
required this.onControllerCreated,
required this.onControllerDestroyed});
@override
State<StatefulWidget> createState() => _ControllerMenuState();
}
class _ControllerMenuState extends State<ControllerMenu> {
FilamentController? _filamentController;
final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Camera Menu');
void _createController({String? uberArchivePath}) {
if (_filamentController != null) {
throw Exception("Controller already exists");
}
_filamentController =
FilamentControllerFFI(uberArchivePath: uberArchivePath);
widget.onControllerCreated(_filamentController!);
}
@override
void initState() {
super.initState();
_filamentController = widget.controller;
}
@override
void didUpdateWidget(ControllerMenu oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.controller != _filamentController) {
setState(() {
_filamentController = widget.controller;
});
}
}
@override
Widget build(BuildContext context) {
var items = <Widget>[];
if (_filamentController?.hasViewer.value != true) {
items.addAll([
MenuItemButton(
child: const Text("Create FilamentViewer"),
onPressed: _filamentController == null
? null
: () {
_filamentController!.createViewer();
},
),
MenuItemButton(
child: const Text("Create FilamentController (default ubershader)"),
onPressed: () {
_createController();
},
),
MenuItemButton(
child: const Text(
"Create FilamentController (custom ubershader - lit opaque only)"),
onPressed: () {
_createController(
uberArchivePath: Platform.isWindows
? "assets/lit_opaque_32.uberz"
: Platform.isMacOS
? "assets/lit_opaque_43.uberz"
: Platform.isIOS
? "assets/lit_opaque_43.uberz"
: "assets/lit_opaque_43_gles.uberz");
},
)
]);
} else {
items.addAll([
MenuItemButton(
child: const Text("Destroy viewer"),
onPressed: () {
_filamentController!.destroy();
_filamentController = null;
widget.onControllerDestroyed();
setState(() {});
},
)
]);
}
return MenuAnchor(
childFocusNode: _buttonFocusNode,
menuChildren: items,
builder:
(BuildContext context, MenuController controller, Widget? child) {
return Align(
alignment: Alignment.bottomLeft,
child: TextButton(
onPressed: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
child: const Text("Controller / Viewer"),
));
});
}
}

View File

@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament_example/main.dart';
class RenderingSubmenu extends StatefulWidget {
final FilamentController controller;
const RenderingSubmenu({super.key, required this.controller});
@override
State<StatefulWidget> createState() => _RenderingSubmenuState();
}
class _RenderingSubmenuState extends State<RenderingSubmenu> {
@override
Widget build(BuildContext context) {
return SubmenuButton(
menuChildren: [
MenuItemButton(
onPressed: () {
widget.controller.render();
},
child: const Text("Render single frame"),
),
MenuItemButton(
onPressed: () {
ExampleWidgetState.rendering = !ExampleWidgetState.rendering;
widget.controller.setRendering(ExampleWidgetState.rendering);
},
child: Text(
"Set continuous rendering to ${!ExampleWidgetState.rendering}"),
),
MenuItemButton(
onPressed: () {
ExampleWidgetState.framerate =
ExampleWidgetState.framerate == 60 ? 30 : 60;
widget.controller.setFrameRate(ExampleWidgetState.framerate);
},
child: Text(
"Toggle framerate (currently $ExampleWidgetState.framerate) "),
),
MenuItemButton(
onPressed: () {
widget.controller.setToneMapping(ToneMapper.LINEAR);
},
child: const Text("Set tone mapping to linear"),
),
MenuItemButton(
onPressed: () {
ExampleWidgetState.postProcessing =
!ExampleWidgetState.postProcessing;
widget.controller
.setPostProcessing(ExampleWidgetState.postProcessing);
},
child: Text(
"${ExampleWidgetState.postProcessing ? "Disable" : "Enable"} postprocessing"),
),
],
child: const Text("Rendering"),
);
}
}

View File

@@ -0,0 +1,68 @@
import 'package:flutter/material.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament_example/menus/asset_submenu.dart';
import 'package:flutter_filament_example/menus/camera_submenu.dart';
import 'package:flutter_filament_example/menus/rendering_submenu.dart';
class SceneMenu extends StatefulWidget {
final FilamentController? controller;
const SceneMenu({super.key, required this.controller});
@override
State<StatefulWidget> createState() {
return _SceneMenuState();
}
}
class _SceneMenuState extends State<SceneMenu> {
@override
void didUpdateWidget(SceneMenu oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.controller != null &&
widget.controller != oldWidget.controller ||
widget.controller!.hasViewer != oldWidget.controller!.hasViewer) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable:
widget.controller?.hasViewer ?? ValueNotifier<bool>(false),
builder: (BuildContext ctx, bool hasViewer, Widget? child) {
return MenuAnchor(
menuChildren: widget.controller == null
? []
: <Widget>[
RenderingSubmenu(
controller: widget.controller!,
),
AssetSubmenu(controller: widget.controller!),
CameraSubmenu(
controller: widget.controller!,
),
],
builder: (BuildContext context, MenuController controller,
Widget? child) {
return Align(
alignment: Alignment.bottomLeft,
child: TextButton(
onPressed: !hasViewer
? null
: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
child: const Text("Scene"),
));
},
);
});
}
}

View File

@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import 'package:flutter_filament/filament_controller.dart';
class PickerResultWidget extends StatelessWidget {
final FilamentController controller;
const PickerResultWidget({required this.controller, super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: controller.pickResult.map((FilamentEntity? entityId) {
if (entityId == null) {
return null;
}
return controller.getNameForEntity(entityId);
}),
builder: (ctx, snapshot) => snapshot.data == null
? Container()
: Text(snapshot.data!,
style: const TextStyle(color: Colors.green, fontSize: 24)));
}
}

View File

@@ -4,10 +4,10 @@ project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "polyvox_filament_example")
set(BINARY_NAME "flutter_filament_example")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "app.polyvox.polyvox_filament")
set(APPLICATION_ID "app.polyvox.flutter_filament")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.

View File

@@ -6,10 +6,10 @@
#include "generated_plugin_registrant.h"
#include <polyvox_filament/polyvox_filament_plugin.h>
#include <flutter_filament/flutter_filament_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) polyvox_filament_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "PolyvoxFilamentPlugin");
polyvox_filament_plugin_register_with_registrar(polyvox_filament_registrar);
g_autoptr(FlPluginRegistrar) flutter_filament_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterFilamentPlugin");
flutter_filament_plugin_register_with_registrar(flutter_filament_registrar);
}

View File

@@ -3,7 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
polyvox_filament
flutter_filament
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "polyvox_filament_example");
gtk_header_bar_set_title(header_bar, "flutter_filament_example");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "polyvox_filament_example");
gtk_window_set_title(window, "flutter_filament_example");
}
gtk_window_set_default_size(window, 1280, 720);

View File

@@ -5,10 +5,10 @@
import FlutterMacOS
import Foundation
import flutter_filament
import path_provider_foundation
import polyvox_filament
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SwiftFlutterFilamentPlugin.register(with: registry.registrar(forPlugin: "SwiftFlutterFilamentPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SwiftPolyvoxFilamentPlugin.register(with: registry.registrar(forPlugin: "SwiftPolyvoxFilamentPlugin"))
}

View File

@@ -1,21 +1,28 @@
PODS:
- flutter_filament (0.0.1):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- polyvox_filament (0.0.1):
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- flutter_filament (from `Flutter/ephemeral/.symlinks/plugins/flutter_filament/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- polyvox_filament (from `Flutter/ephemeral/.symlinks/plugins/polyvox_filament/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
EXTERNAL SOURCES:
flutter_filament:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_filament/macos
FlutterMacOS:
:path: Flutter/ephemeral
polyvox_filament:
:path: Flutter/ephemeral/.symlinks/plugins/polyvox_filament/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
SPEC CHECKSUMS:
flutter_filament: ddf9db01d70cce6c8f3a34f414562ebdb43c7f36
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
polyvox_filament: 59a161de3df49c867bc2003d4ff73b8a304d2feb
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
PODFILE CHECKSUM: 9cc8fc8fc62b1d9a89fd6f974ad4157b35254030

View File

@@ -575,6 +575,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13;
ONLY_ACTIVE_ARCH = YES;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
@@ -723,6 +724,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13;
ONLY_ACTIVE_ARCH = YES;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<false/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.server</key>

View File

@@ -28,5 +28,7 @@
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>com.apple.security.app-sandbox</key>
<false/>
</dict>
</plist>

7
example/makefile Normal file
View File

@@ -0,0 +1,7 @@
include ../makefile
# building on MacOS, we currently just delete the macos/include
# and macos/src directories and copy from iOS
sync-libs-macos-and-update-pods: sync-libs-macos
pushd macos && pod update

View File

@@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03"
url: "https://pub.dev"
source: hosted
version: "3.4.6"
async:
dependency: transitive
description:
@@ -37,10 +45,26 @@ packages:
dependency: transitive
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: "direct dev"
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
@@ -65,11 +89,31 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_driver:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_filament:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.5.0"
flutter_lints:
dependency: "direct dev"
description:
@@ -88,6 +132,40 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
fuchsia_remote_debug_protocol:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
image:
dependency: transitive
description:
name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
url: "https://pub.dev"
source: hosted
version: "3.3.0"
image_compare:
dependency: "direct dev"
description:
name: image_compare
sha256: "774e9ef1558ca328191fe9690e8e024159a3a2db6ea4ef6b65bea0faa3631b74"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
integration_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
intl:
dependency: transitive
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.1"
js:
dependency: transitive
description:
@@ -96,6 +174,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: f38a2c91c12f31726ca13015fbab3d2e9440edcb7c17b8b36ed9b85ed6eee6a2
url: "https://pub.dev"
source: hosted
version: "9.0.11"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "23770c69594f5260a79fe9d84e29f8b175d1b05d128e751c904b3cdf910e5dfc"
url: "https://pub.dev"
source: hosted
version: "1.0.9"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: b06739349ec2477e943055aea30172c5c7000225f79dad4702e2ec0eda79a6ff
url: "https://pub.dev"
source: hosted
version: "1.0.5"
lints:
dependency: transitive
description:
@@ -116,18 +218,18 @@ packages:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.11.0"
path:
dependency: transitive
description:
@@ -184,14 +286,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.1"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8"
url: "https://pub.dev"
source: hosted
version: "11.0.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e
url: "https://pub.dev"
source: hosted
version: "11.1.0"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
url: "https://pub.dev"
source: hosted
version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
url: "https://pub.dev"
source: hosted
version: "3.12.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
url: "https://pub.dev"
source: hosted
version: "0.1.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6
url: "https://pub.dev"
source: hosted
version: "6.0.1"
platform:
dependency: transitive
description:
name: platform
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "3.1.3"
plugin_platform_interface:
dependency: transitive
description:
@@ -200,13 +350,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.6"
polyvox_filament:
dependency: "direct main"
pointycastle:
dependency: transitive
description:
path: ".."
relative: true
source: path
version: "0.0.1"
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.7.3"
process:
dependency: transitive
description:
name: process
sha256: "266ca5be5820feefc777793d0a583acfc8c40834893c87c00c6c09e2cf58ea42"
url: "https://pub.dev"
source: hosted
version: "5.0.1"
sky_engine:
dependency: transitive
description: flutter
@@ -224,18 +383,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
string_scanner:
dependency: transitive
description:
@@ -244,6 +403,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
sync_http:
dependency: transitive
description:
name: sync_http
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
url: "https://pub.dev"
source: hosted
version: "0.3.1"
term_glyph:
dependency: transitive
description:
@@ -256,10 +423,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.6.1"
tuple:
dependency: transitive
description:
@@ -268,6 +435,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
universal_io:
dependency: transitive
description:
name: universal_io
sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
vector_math:
dependency: transitive
description:
@@ -276,30 +459,46 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
wasm_ffi:
vm_service:
dependency: transitive
description:
name: wasm_ffi
sha256: "5da66560305dd659d62caef535c5314abd9302c122e6eef8681e6879fbbfe358"
name: vm_service
sha256: a13d5503b4facefc515c8c587ce3cf69577a7b064a9f1220e005449cf1f64aad
url: "https://pub.dev"
source: hosted
version: "0.9.4"
version: "12.0.0"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
url: "https://pub.dev"
source: hosted
version: "2.4.0"
webdriver:
dependency: transitive
description:
name: webdriver
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
win32:
dependency: transitive
description:
name: win32
sha256: c97defd418eef4ec88c0d1652cdce84b9f7b63dd7198e266d06ac1710d527067
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
url: "https://pub.dev"
source: hosted
version: "5.0.8"
version: "5.0.9"
xdg_directories:
dependency: transitive
description:
@@ -308,6 +507,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556
url: "https://pub.dev"
source: hosted
version: "6.4.2"
sdks:
dart: ">=3.1.0-185.0.dev <3.11.0"
flutter: ">=3.7.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.16.0-0.2.pre"

View File

@@ -1,12 +1,12 @@
name: polyvox_filament_example
description: Demonstrates how to use the polyvox_filament plugin.
name: flutter_filament_example
description: Demonstrates how to use the flutter_filament plugin.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: ">=2.12.0 <4.0.0"
sdk: ">=3.0.0 <4.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@@ -18,15 +18,19 @@ dependencies:
flutter:
sdk: flutter
path_provider:
polyvox_filament:
flutter_filament:
path: ../
permission_handler:
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
flutter_lints: ^1.0.0
crypto:
image_compare: ^1.1.2
# For information on the generic Dart part of this file, see the

View File

@@ -0,0 +1,8 @@
#!/bin/bash
device=$1
if [ -z "$device" ]; then
echo "Usage: $0 <device_id>"
exit 1;
fi
rm -f integration_test/goldens/{ios,macos,windows,android}/*.png
flutter drive --driver=test_driver/integration_test_update_goldens.dart -d $1 --target=integration_test/plugin_integration_test.dart

View File

@@ -8,7 +8,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:polyvox_filament_example/main.dart';
import 'package:flutter_filament_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {

View File

@@ -0,0 +1,58 @@
import 'dart:io';
import 'package:integration_test/integration_test_driver_extended.dart';
import 'package:image_compare/image_compare.dart';
Future<void> main() async {
await integrationDriver(
onScreenshot: (
String screenshotName,
List<int> screenshotBytes, [
Map<String, Object?>? args,
]) async {
final dir = screenshotName.split("/")[0];
final name = screenshotName.split("/")[1];
final File golden = await File('integration_test/goldens/$dir/$name.png');
if (!golden.existsSync()) {
throw Exception(
"Golden image ${golden.path} doesn't exist yet. Make sure you have run integraton_test_update_goldens.dart first");
}
var result = await compareImages(
src1: screenshotBytes,
src2: golden.readAsBytesSync(),
algorithm: ChiSquareDistanceHistogram());
print(result);
// TODO - it would be preferable to use Flutter's GoldenFileComparator here, e.g.
//
// ```var comparator = LocalFileComparator(testImage.uri);
// comparator.compare(imageBytes, golden)
// comparator.getFailureFile(failure, golden, basedir)
// var result = await comparator.compare(
// Uint8List.fromList(screenshotBytes), golden.uri);
// if (!result.passed) {
// for (var key in result.diffs!.keys) {
// var byteData = await result.diffs![key]!.toByteData();
// File('integration_test/goldens/$dir/diffs/$name.png')
// .writeAsBytesSync(
// byteData!.buffer.asUint8List(byteData!.offsetInBytes));
// }
// return false;
// }```
// but this is only available via a Flutter shell which is currently unavailable (this script is run as a plain Dart file I guess).
// let's revisit if/when this changes
// see https://github.com/flutter/flutter/issues/51890 and https://github.com/flutter/flutter/issues/103222
if (result > 0.005) {
File('integration_test/goldens/$dir/diffs/$name.png')
.writeAsBytesSync(screenshotBytes);
return false;
}
return true;
},
);
}

View File

@@ -0,0 +1,22 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:integration_test/integration_test_driver_extended.dart';
Future<void> main() async {
await integrationDriver(
onScreenshot: (
String screenshotName,
List<int> screenshotBytes, [
Map<String, Object?>? args,
]) async {
final dir = screenshotName.split("/")[0];
final name = screenshotName.split("/")[1];
final File image = await File('integration_test/goldens/$dir/$name.png')
.create(recursive: true);
image.writeAsBytesSync(screenshotBytes);
return true;
},
);
}

View File

@@ -18,18 +18,18 @@
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="Demonstrates how to use the polyvox_filament plugin.">
<meta name="description" content="Demonstrates how to use the flutter_filament plugin.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="polyvox_filament_example">
<meta name="apple-mobile-web-app-title" content="flutter_filament_example">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>polyvox_filament_example</title>
<title>flutter_filament_example</title>
<link rel="manifest" href="manifest.json">
<script>

View File

@@ -1,11 +1,11 @@
{
"name": "polyvox_filament_example",
"short_name": "polyvox_filament_example",
"name": "flutter_filament_example",
"short_name": "flutter_filament_example",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "Demonstrates how to use the polyvox_filament plugin.",
"description": "Demonstrates how to use the flutter_filament plugin.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)
project(polyvox_filament_example LANGUAGES CXX)
project(flutter_filament_example LANGUAGES CXX)
set(BINARY_NAME "polyvox_filament_example")
set(BINARY_NAME "flutter_filament_example")
cmake_policy(SET CMP0063 NEW)

View File

@@ -6,9 +6,12 @@
#include "generated_plugin_registrant.h"
#include <polyvox_filament/polyvox_filament_plugin_c_api.h>
#include <flutter_filament/flutter_filament_plugin_c_api.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
PolyvoxFilamentPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PolyvoxFilamentPluginCApi"));
FlutterFilamentPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterFilamentPluginCApi"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
}

View File

@@ -3,7 +3,8 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
polyvox_filament
flutter_filament
permission_handler_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@@ -90,12 +90,12 @@ BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "app.polyvox" "\0"
VALUE "FileDescription", "polyvox_filament_example" "\0"
VALUE "FileDescription", "flutter_filament_example" "\0"
VALUE "FileVersion", VERSION_AS_STRING "\0"
VALUE "InternalName", "polyvox_filament_example" "\0"
VALUE "InternalName", "flutter_filament_example" "\0"
VALUE "LegalCopyright", "Copyright (C) 2022 app.polyvox. All rights reserved." "\0"
VALUE "OriginalFilename", "polyvox_filament_example.exe" "\0"
VALUE "ProductName", "polyvox_filament_example" "\0"
VALUE "OriginalFilename", "flutter_filament_example.exe" "\0"
VALUE "ProductName", "flutter_filament_example" "\0"
VALUE "ProductVersion", VERSION_AS_STRING "\0"
END
END

View File

@@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"polyvox_filament_example", origin, size)) {
if (!window.CreateAndShow(L"flutter_filament_example", origin, size)) {
return EXIT_FAILURE;
}
window.SetQuitOnClose(true);

View File

@@ -1,4 +1,4 @@
#import <Flutter/Flutter.h>
@interface PolyvoxFilamentPlugin : NSObject<FlutterPlugin>
@interface FlutterFilamentPlugin : NSObject<FlutterPlugin>
@end

View File

@@ -1,18 +1,18 @@
#import "PolyvoxFilamentPlugin.h"
#if __has_include(<polyvox_filament/polyvox_filament-Swift.h>)
#import <polyvox_filament/polyvox_filament-Swift.h>
#import "FlutterFilamentPlugin.h"
#if __has_include(<flutter_filament/flutter_filament-Swift.h>)
#import <flutter_filament/flutter_filament-Swift.h>
#else
// Support project import fallback if the generated compatibility header
// is not copied when this plugin is created as a library.
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
#import "polyvox_filament-Swift.h"
#import "flutter_filament-Swift.h"
#endif
#include "PolyvoxFilamentApi.h"
#include "FlutterFilamentApi.h"
@implementation PolyvoxFilamentPlugin
@implementation FlutterFilamentPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
[SwiftPolyvoxFilamentPlugin registerWithRegistrar:registrar];
[SwiftFlutterFilamentPlugin registerWithRegistrar:registrar];
ios_dummy();
}
@end

View File

@@ -2,7 +2,7 @@ import Flutter
import UIKit
import GLKit
public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture {
public class SwiftFlutterFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture {
var registrar : FlutterPluginRegistrar
var flutterTextureId: Int64?
@@ -25,7 +25,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
var loadResource : @convention(c) (UnsafePointer<Int8>?, UnsafeMutableRawPointer?) -> ResourceBuffer = { uri, resourcesPtr in
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr!).takeUnretainedValue()
let instance:SwiftFlutterFilamentPlugin = Unmanaged<SwiftFlutterFilamentPlugin>.fromOpaque(resourcesPtr!).takeUnretainedValue()
let uriString = String(cString:uri!)
@@ -121,12 +121,12 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
}
var freeResource : @convention(c) (ResourceBuffer,UnsafeMutableRawPointer?) -> () = { rbuf, resourcesPtr in
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr!).takeUnretainedValue()
let instance:SwiftFlutterFilamentPlugin = Unmanaged<SwiftFlutterFilamentPlugin>.fromOpaque(resourcesPtr!).takeUnretainedValue()
instance.resources.removeObject(forKey:rbuf.id)
}
var markTextureFrameAvailable : @convention(c) (UnsafeMutableRawPointer?) -> () = { instancePtr in
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(instancePtr!).takeUnretainedValue()
let instance:SwiftFlutterFilamentPlugin = Unmanaged<SwiftFlutterFilamentPlugin>.fromOpaque(instancePtr!).takeUnretainedValue()
instance.registry.textureFrameAvailable(instance.flutterTextureId!)
}
@@ -145,7 +145,7 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
let _messenger = registrar.messenger();
messenger = _messenger;
let channel = FlutterMethodChannel(name: "app.polyvox.filament/event", binaryMessenger: _messenger)
let instance = SwiftPolyvoxFilamentPlugin(textureRegistry: registrar.textures(), registrar:registrar)
let instance = SwiftFlutterFilamentPlugin(textureRegistry: registrar.textures(), registrar:registrar)
registrar.addMethodCallDelegate(instance, channel: channel)
}
@@ -166,8 +166,6 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let methodName = call.method;
switch methodName {
case "getSharedContext":
result(nil)
case "getResourceLoaderWrapper":
let resourceLoaderWrapper = make_resource_loader(loadResource, freeResource, Unmanaged.passUnretained(self).toOpaque())
result(unsafeBitCast(resourceLoaderWrapper, to:Int64.self))
@@ -180,24 +178,14 @@ public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture
createPixelBuffer(width:Int(args[0]), height:Int(args[1]))
let pixelBufferPtr = unsafeBitCast(pixelBuffer!, to:UnsafeRawPointer.self)
let pixelBufferAddress = Int(bitPattern:pixelBufferPtr);
result([self.flutterTextureId, pixelBufferAddress, nil])
result([self.flutterTextureId, pixelBufferAddress, nil, nil])
case "destroyTexture":
if(self.flutterTextureId != nil) {
self.registry.unregisterTexture(self.flutterTextureId!)
}
self.flutterTextureId = nil
self.pixelBuffer = nil
case "resize":
let args = call.arguments as! [Any]
let width = UInt32(args[0] as! Int64)
let height = UInt32(args[1] as! Int64)
if(self.flutterTextureId != nil) {
self.registry.unregisterTexture(self.flutterTextureId!)
}
createPixelBuffer(width: Int(width), height:Int(height))
var pixelBufferTextureId = unsafeBitCast(pixelBuffer!, to: UnsafeRawPointer.self)
print("Resized to \(args[0])x\(args[1])")
result(self.flutterTextureId);
result(true)
case "dummy":
ios_dummy()
ios_dummy_ffi()

View File

@@ -1,9 +1,9 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint polyvox_filament.podspec` to validate before publishing.
# Run `pod lib lint flutter_filament.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'polyvox_filament'
s.name = 'flutter_filament'
s.version = '0.0.1'
s.summary = 'A new flutter plugin project.'
s.description = <<-DESC
@@ -14,7 +14,7 @@ A new flutter plugin project.
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/*', 'src/*', "src/camutils/*", 'src/ios/*', 'include/filament/*', 'include/*', 'include/material/*.c'
s.public_header_files = 'include/SwiftPolyvoxFilamentPlugin-Bridging-Header.h', 'include/PolyvoxFilamentApi.h', 'include/PolyvoxFilamentFFIApi.h', 'include/ResourceBuffer.hpp', 'include/Log.hpp'
s.public_header_files = 'include/SwiftFlutterFilamentPlugin-Bridging-Header.h', 'include/FlutterFilamentApi.h', 'include/FlutterFilamentFFIApi.h', 'include/ResourceBuffer.hpp', 'include/Log.hpp'
s.dependency 'Flutter'
s.platform = :ios, '12.1'
s.static_framework = true
@@ -24,10 +24,10 @@ A new flutter plugin project.
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
'OTHER_CFLAGS' => '"-fvisibility=default" "$(inherited)"',
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include/filament" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/shaders" "$(inherited)"',
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/include/filament" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/src/image" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/src/shaders" "$(inherited)"',
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -limageio -ltinyexr -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -lpng -lpng16 -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd -lstdc++',
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/lib" "$(inherited)"',
}
s.pod_target_xcconfig = {
@@ -36,10 +36,10 @@ A new flutter plugin project.
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "-fvisibility=default" "$(inherited)"',
'OTHER_CFLAGS' => '"-fvisibility=default" "$(inherited)"',
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include/filament" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/shaders" "$(inherited)"',
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/include/filament" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/src/image" "${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/src/shaders" "$(inherited)"',
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -limageio -ltinyexr -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -lpng -lpng16 -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd -lstdc++',
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/flutter_filament/ios/lib" "$(inherited)"',
}
s.swift_version = '5.0'

View File

@@ -1,5 +1,7 @@
#pragma once
#include <mutex>
#include <filament/Scene.h>
#include <gltfio/AssetLoader.h>
@@ -82,6 +84,7 @@ namespace polyvox {
gltfio::ResourceLoader* _gltfResourceLoader = nullptr;
gltfio::TextureProvider* _stbDecoder = nullptr;
gltfio::TextureProvider* _ktxDecoder = nullptr;
std::mutex _animationMutex;
vector<SceneAsset> _assets;
tsl::robin_map<EntityId, int> _entityIdLookup;

View File

@@ -1,6 +1,7 @@
#pragma once
#include <filament/Camera.h>
#include <filament/Frustum.h>
#include <filament/ColorGrading.h>
#include <filament/Engine.h>
#include <filament/IndexBuffer.h>
@@ -41,149 +42,153 @@ using namespace camutils;
typedef int32_t EntityId;
namespace polyvox {
namespace polyvox
{
enum ToneMapping {
ACES, FILMIC, LINEAR
};
class FilamentViewer {
public:
FilamentViewer(const void* context, const ResourceLoaderWrapper* const resourceLoaderWrapper, void* const platform=nullptr, const char* uberArchivePath=nullptr);
~FilamentViewer();
void setToneMapping(ToneMapping toneMapping);
void setBloom(float strength);
void loadSkybox(const char* const skyboxUri);
void removeSkybox();
void loadIbl(const char* const iblUri, float intensity);
void removeIbl();
void removeAsset(EntityId asset);
// removes all add assets from the current scene
void clearAssets();
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
void render(
uint64_t frameTimeInNanos,
void* pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void* data
);
void setFrameInterval(float interval);
bool setCamera(EntityId asset, const char* nodeName);
void createSwapChain(const void* surface, uint32_t width, uint32_t height);
void destroySwapChain();
void createRenderTarget(intptr_t textureId, uint32_t width,uint32_t height);
Renderer* getRenderer();
void setBackgroundColor(const float r, const float g, const float b, const float a);
void setBackgroundImage(const char* resourcePath, bool fillHeight);
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);
void setCameraModelMatrix(const float* const matrix);
void setCameraFocalLength(float fl);
void setCameraFocusDistance(float focusDistance);
void grabBegin(float x, float y, bool pan);
void grabUpdate(float x, float y);
void grabEnd();
void scrollBegin();
void scrollUpdate(float x, float y, float delta);
void scrollEnd();
int32_t addLight(LightManager::Type t, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
void removeLight(EntityId entityId);
void clearLights();
void setPostProcessing(bool enabled);
void pick(uint32_t x, uint32_t y, EntityId* entityId);
AssetManager* const getAssetManager() {
return (AssetManager* const) _assetManager;
}
private:
void createImageRenderable();
void loadResources(std::string relativeResourcePath);
void cleanup();
bool _panning = false;
float _startX;
float _startY;
math::mat4f _cameraPosition;
math::mat4f _cameraRotation;
const ResourceLoaderWrapper* const _resourceLoaderWrapper;
Scene* _scene;
View* _view;
Engine* _engine;
// a default camera that we add to every scene
Camera* _mainCamera;
Renderer* _renderer;
RenderTarget* _rt;
Texture* _rtColor;
Texture* _rtDepth;
SwapChain* _swapChain = nullptr;
AssetManager* _assetManager = nullptr;
NameComponentManager* _ncm = nullptr;
std::mutex mtx; // mutex to ensure thread safety when removing assets
vector<utils::Entity> _lights;
Texture* _skyboxTexture = nullptr;
Skybox* _skybox = nullptr;
Texture* _iblTexture = nullptr;
IndirectLight* _indirectLight = nullptr;
bool _recomputeAabb = false;
bool _actualSize = false;
float _cameraFocalLength = 28.0f;
float _cameraFocusDistance = 0.0f;
ColorGrading *colorGrading = nullptr;
// background image properties
uint32_t _imageHeight = 0;
uint32_t _imageWidth = 0;
mat4f _imageScale;
Texture* _imageTexture = nullptr;
utils::Entity* _imageEntity = nullptr;
VertexBuffer* _imageVb = nullptr;
IndexBuffer* _imageIb = nullptr;
Material* _imageMaterial = nullptr;
TextureSampler _imageSampler;
void loadKtx2Texture(string path, ResourceBuffer data);
void loadKtxTexture(string path, ResourceBuffer data);
void loadPngTexture(string path, ResourceBuffer data);
void loadTextureFromPath(string path);
Manipulator<double>* _manipulator = nullptr;
void _createManipulator();
uint32_t _lastFrameTimeInNanos;
enum ToneMapping
{
ACES,
FILMIC,
LINEAR
};
class FilamentViewer
{
public:
FilamentViewer(const void *context, const ResourceLoaderWrapper *const resourceLoaderWrapper, void *const platform = nullptr, const char *uberArchivePath = nullptr);
~FilamentViewer();
void setToneMapping(ToneMapping toneMapping);
void setBloom(float strength);
void loadSkybox(const char *const skyboxUri);
void removeSkybox();
void loadIbl(const char *const iblUri, float intensity);
void removeIbl();
void removeAsset(EntityId asset);
void clearAssets();
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
void render(
uint64_t frameTimeInNanos,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data);
void setFrameInterval(float interval);
bool setCamera(EntityId asset, const char *nodeName);
void createSwapChain(const void *surface, uint32_t width, uint32_t height);
void destroySwapChain();
void createRenderTarget(intptr_t textureId, uint32_t width, uint32_t height);
Renderer *getRenderer();
void setBackgroundColor(const float r, const float g, const float b, const float a);
void setBackgroundImage(const char *resourcePath, bool fillHeight);
void clearBackgroundImage();
void setBackgroundImagePosition(float x, float y, bool clamp);
// Camera methods
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);
const math::mat4 getCameraModelMatrix();
const math::mat4 getCameraViewMatrix();
const math::mat4 getCameraProjectionMatrix();
const math::mat4 getCameraCullingProjectionMatrix();
const filament::Frustum getCameraFrustum();
void setCameraModelMatrix(const float *const matrix);
void setCameraProjectionMatrix(const double *const matrix, double near, double far);
void setCameraFocalLength(float fl);
void setCameraFocusDistance(float focusDistance);
void setCameraManipulatorOptions(filament::camutils::Mode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed);
void grabBegin(float x, float y, bool pan);
void grabUpdate(float x, float y);
void grabEnd();
void scrollBegin();
void scrollUpdate(float x, float y, float delta);
void scrollEnd();
void pick(uint32_t x, uint32_t y, EntityId *entityId);
EntityId addLight(LightManager::Type t, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
void removeLight(EntityId entityId);
void clearLights();
void setPostProcessing(bool enabled);
AssetManager *const getAssetManager()
{
return (AssetManager *const)_assetManager;
}
private:
const ResourceLoaderWrapper *const _resourceLoaderWrapper;
Scene *_scene = nullptr;
View *_view = nullptr;
Engine *_engine = nullptr;
Renderer *_renderer = nullptr;
RenderTarget *_rt = nullptr;
Texture *_rtColor = nullptr;
Texture *_rtDepth = nullptr;
SwapChain *_swapChain = nullptr;
AssetManager *_assetManager = nullptr;
NameComponentManager *_ncm = nullptr;
std::mutex mtx; // mutex to ensure thread safety when removing assets
vector<utils::Entity> _lights;
Texture *_skyboxTexture = nullptr;
Skybox *_skybox = nullptr;
Texture *_iblTexture = nullptr;
IndirectLight *_indirectLight = nullptr;
bool _recomputeAabb = false;
bool _actualSize = false;
// Camera properties
Camera *_mainCamera = nullptr; // the default camera added to every scene. If you want the *active* camera, access via View.
float _cameraFocalLength = 28.0f;
float _cameraFocusDistance = 0.0f;
Manipulator<double> *_manipulator = nullptr;
filament::camutils::Mode _manipulatorMode = filament::camutils::Mode::ORBIT;
double _orbitSpeedX = 0.01;
double _orbitSpeedY = 0.01;
double _zoomSpeed = 0.01;
math::mat4f _cameraPosition;
math::mat4f _cameraRotation;
void _createManipulator();
ColorGrading *colorGrading = nullptr;
// background image properties
uint32_t _imageHeight = 0;
uint32_t _imageWidth = 0;
mat4f _imageScale;
Texture *_imageTexture = nullptr;
utils::Entity *_imageEntity = nullptr;
VertexBuffer *_imageVb = nullptr;
IndexBuffer *_imageIb = nullptr;
Material *_imageMaterial = nullptr;
TextureSampler _imageSampler;
void loadKtx2Texture(string path, ResourceBuffer data);
void loadKtxTexture(string path, ResourceBuffer data);
void loadPngTexture(string path, ResourceBuffer data);
void loadTextureFromPath(string path);
uint32_t _lastFrameTimeInNanos;
};
}

View File

@@ -1,5 +1,5 @@
#ifndef _POLYVOX_FILAMENT_API_H
#define _POLYVOX_FILAMENT_API_H
#ifndef _FLUTTER_FILAMENT_API_H
#define _FLUTTER_FILAMENT_API_H
#ifdef _WIN32
#ifdef IS_DLL
@@ -47,11 +47,11 @@
#include "ResourceBuffer.hpp"
typedef int32_t EntityId;
typedef int32_t _ManipulatorMode;
#ifdef __cplusplus
extern "C" {
#endif
typedef int32_t EntityId;
FLUTTER_PLUGIN_EXPORT const void* create_filament_viewer(const void* const context, const ResourceLoaderWrapper* const loader, void* const platform, const char* uberArchivePath);
FLUTTER_PLUGIN_EXPORT void destroy_filament_viewer(const void* const viewer);
@@ -140,20 +140,33 @@ FLUTTER_PLUGIN_EXPORT void transform_to_unit_cube(void* assetManager, EntityId a
FLUTTER_PLUGIN_EXPORT void set_position(void* assetManager, EntityId asset, float x, float y, float z);
FLUTTER_PLUGIN_EXPORT void set_rotation(void* assetManager, EntityId asset, float rads, float x, float y, float z);
FLUTTER_PLUGIN_EXPORT void set_scale(void* assetManager, EntityId asset, float scale);
// Camera methods
FLUTTER_PLUGIN_EXPORT void move_camera_to_asset(const void* const viewer, EntityId asset);
FLUTTER_PLUGIN_EXPORT void set_view_frustum_culling(const void* const viewer, bool enabled);
FLUTTER_PLUGIN_EXPORT void set_camera_exposure(const void* const viewer, float aperture, float shutterSpeed, float sensitivity);
FLUTTER_PLUGIN_EXPORT void set_camera_position(const void* const viewer, float x, float y, float z);
FLUTTER_PLUGIN_EXPORT void get_camera_position(const void* const viewer);
FLUTTER_PLUGIN_EXPORT void set_camera_rotation(const void* const viewer, float rads, float x, float y, float z);
FLUTTER_PLUGIN_EXPORT void set_camera_model_matrix(const void* const viewer, const float *const matrix);
FLUTTER_PLUGIN_EXPORT const double* const get_camera_model_matrix(const void* const viewer);
FLUTTER_PLUGIN_EXPORT const double* const get_camera_view_matrix(const void* const viewer);
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 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);
FLUTTER_PLUGIN_EXPORT void set_camera_focus_distance(const void* const viewer, float focusDistance);
FLUTTER_PLUGIN_EXPORT void set_camera_manipulator_options(const void* const viewer, _ManipulatorMode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed);
FLUTTER_PLUGIN_EXPORT int hide_mesh(void* assetManager, EntityId asset, const char* meshName);
FLUTTER_PLUGIN_EXPORT int reveal_mesh(void* assetManager, EntityId asset, const char* meshName);
FLUTTER_PLUGIN_EXPORT void set_post_processing(void* const viewer, bool enabled);
FLUTTER_PLUGIN_EXPORT void pick(void* const viewer, int x, int y, EntityId* entityId);
FLUTTER_PLUGIN_EXPORT const char* get_name_for_entity(void* const assetManager, const EntityId entityId);
FLUTTER_PLUGIN_EXPORT void ios_dummy();
FLUTTER_PLUGIN_EXPORT void flutter_filament_free(void* ptr);
#ifdef __cplusplus
}
#endif

View File

@@ -1,15 +1,15 @@
#ifndef _POLYVOX_FILAMENT_FFI_API_H
#define _POLYVOX_FILAMENT_FFI_API_H
#ifndef _FLUTTER_FILAMENT_FFI_API_H
#define _FLUTTER_FILAMENT_FFI_API_H
#include "PolyvoxFilamentApi.h"
#include "FlutterFilamentApi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
/// This header replicates most of the methods in PolyvoxFilamentApi.h, and is only intended to be used to generate client FFI bindings.
/// The intention is that calling one of these methods will call its respective method in PolyvoxFilamentApi.h, but wrapped in some kind of thread runner to ensure thread safety.
/// This header replicates most of the methods in FlutterFilamentApi.h, and is only intended to be used to generate client FFI bindings.
/// The intention is that calling one of these methods will call its respective method in FlutterFilamentApi.h, but wrapped in some kind of thread runner to ensure thread safety.
///
typedef int32_t EntityId;
@@ -17,6 +17,7 @@ typedef void (*FilamentRenderCallback)(void* const owner);
FLUTTER_PLUGIN_EXPORT void* const create_filament_viewer_ffi(void* const context, void* const platform, const char* uberArchivePath, const ResourceLoaderWrapper* const loader, void (*renderCallback)(void* const renderCallbackOwner), void* const renderCallbackOwner);
FLUTTER_PLUGIN_EXPORT void create_swap_chain_ffi(void* const viewer, void* const surface, uint32_t width, uint32_t height);
FLUTTER_PLUGIN_EXPORT void destroy_swap_chain_ffi(void* const viewer);
FLUTTER_PLUGIN_EXPORT void create_render_target_ffi(void* const viewer, intptr_t nativeTextureId, uint32_t width, uint32_t height);
FLUTTER_PLUGIN_EXPORT void destroy_filament_viewer_ffi(void* const viewer);
FLUTTER_PLUGIN_EXPORT void render_ffi(void* const viewer);
@@ -91,4 +92,4 @@ FLUTTER_PLUGIN_EXPORT void ios_dummy_ffi();
}
#endif
#endif // _POLYVOX_FILAMENT_FFI_API_H
#endif // _FLUTTER_FILAMENT_FFI_API_H

View File

@@ -0,0 +1,4 @@
#import <Flutter/Flutter.h>
@interface FlutterFilamentPlugin : NSObject<FlutterPlugin>
@end

View File

@@ -1,13 +1,13 @@
#pragma once
#ifndef POLYVOX_FILAMENT_LOG_H
#define POLYVOX_FILAMENT_LOG_H
#ifndef FLUTTER_FILAMENT_LOG_H
#define FLUTTER_FILAMENT_LOG_H
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#elif defined __ANDROID__
#include <android/log.h>
#define LOGTAG "PolyvoxFilament"
#define LOGTAG "FlutterFilament"
#else
#include <stdarg.h>
#include <stdio.h>

View File

@@ -1,4 +0,0 @@
#import <Flutter/Flutter.h>
@interface PolyvoxFilamentPlugin : NSObject<FlutterPlugin>
@end

View File

@@ -20,7 +20,7 @@ extern "C" {
#if defined(__cplusplus) && !defined(__ANDROID__) && !defined(__APPLE__)
ResourceBuffer(const void* const data, const int32_t size, const int32_t id) : data(data), size(size), id(id) {};
ResourceBuffer(const ResourceBuffer& rb) : data(rb.data), size(rb.size), id(rb.id) { };
ResourceBuffer(const ResourceBuffer&& rb) : data(rb.data), size(rb.size), id(rb.id) { };
ResourceBuffer(const ResourceBuffer&& rb) noexcept : data(rb.data), size(rb.size), id(rb.id) { };
ResourceBuffer& operator=(const ResourceBuffer& other) = delete;
#endif
};

View File

@@ -20,7 +20,7 @@
#include <utils/NameComponentManager.h>
extern "C" {
#include "PolyvoxFilamentApi.h"
#include "FlutterFilamentApi.h"
}
template class std::vector<float>;
namespace polyvox {

Some files were not shown because too many files have changed in this diff Show More