Compare commits

...

25 Commits

Author SHA1 Message Date
Nick Fisher
4955837518 chore(release): publish packages
- thermion_dart@0.1.1+2
 - thermion_flutter@0.1.1+7
 - thermion_flutter_ffi@0.1.0+6
 - thermion_flutter_platform_interface@0.1.0+6
 - thermion_flutter_web@0.0.1+6
2024-06-26 00:12:32 +08:00
Nick Fisher
0e9cf76592 chore(release): publish packages
- thermion_dart@0.1.1-dev.0+2
 - thermion_flutter@0.1.1-dev.0+7
 - thermion_flutter_platform_interface@0.1.0-dev.0+6
 - thermion_flutter_web@0.0.1-dev.0+6
 - thermion_flutter_ffi@0.1.0-dev.0+6
2024-06-26 00:10:56 +08:00
Nick Fisher
368a341b76 docs: update custom native_toolchain ref for Windows 2024-06-26 01:59:06 +10:00
Nick Fisher
5cc41a9115 docs: update 2024-06-26 01:58:35 +10:00
Nick Fisher
368ce83380 rename thermion_filament namespace to thermion_flutter for Windows 2024-06-26 01:51:31 +10:00
Nick Fisher
683b79c9a0 fix: add ResourceBuffer header directly to Windows build so I don't have to fiddle around getting the CMake path right 2024-06-26 01:50:53 +10:00
Nick Fisher
81be5e25f7 fix: revert to std::thread (pthreads not easily available on Windows) 2024-06-26 01:50:22 +10:00
Nick Fisher
e8e1684694 fix: on Windows, pass static libs via -l rather than custom linkWith property so build.dart stays compatible between published & custom versions 2024-06-26 01:49:37 +10:00
Nick Fisher
d13ecde7b6 update Windows docs 2024-06-26 01:48:08 +10:00
Nick Fisher
08c3af405e Merge pull request #43 from nmfisher/develop
Develop
2024-06-25 21:16:31 +10:00
Nick Fisher
0571f3e653 docs: add Android & Windows pages 2024-06-25 19:04:18 +08:00
Nick Fisher
f351512a78 Merge pull request #42 from Hannnes1/license
Add root LICENSE file
2024-06-25 10:48:00 +10:00
Hannes Hultergård
315b898d7c Add root LICENSE file 2024-06-24 08:28:42 +02:00
Nick Fisher
c635bd3813 chore(release): publish packages
- thermion_dart@0.1.1+1
 - thermion_flutter@0.1.1+6
 - thermion_flutter_web@0.0.1+5
 - thermion_flutter_platform_interface@0.1.0+5
 - thermion_flutter_ffi@0.1.0+5
2024-06-22 10:29:41 +08:00
Nick Fisher
b4f9a5c2af docs: update with links to playground 2024-06-22 10:29:08 +08:00
Nick Fisher
0222ba2d6c chore(release): publish packages
- thermion_dart@0.1.1
2024-06-21 17:18:43 +08:00
Nick Fisher
a066df55f9 chore(release): publish packages
- thermion_dart@0.1.0+4
 - thermion_flutter_web@0.0.1+4
 - thermion_flutter_platform_interface@0.1.0+4
 - thermion_flutter@0.1.1+5
 - thermion_flutter_ffi@0.1.0+4
2024-06-21 16:52:19 +08:00
Nick Fisher
aa85dcfa20 fix: add dummy asset to build.dart on Linux builds so we can use the package on a Linux host 2024-06-21 16:52:10 +08:00
Nick Fisher
a3370a775f chore(release): publish packages
- thermion_dart@0.1.0+3
 - thermion_flutter_web@0.0.1+3
 - thermion_flutter@0.1.1+4
 - thermion_flutter_platform_interface@0.1.0+3
 - thermion_flutter_ffi@0.1.0+3
2024-06-21 16:21:02 +08:00
Nick Fisher
b889fddcfa fix: exit build.dart early on Linux builds so we can use the package on a Linux host 2024-06-21 16:20:42 +08:00
Nick Fisher
090c36c92b chore(release): publish packages
- thermion_dart@0.1.0+2
 - thermion_flutter_ffi@0.1.0+2
 - thermion_flutter_web@0.0.1+2
 - thermion_flutter@0.1.1+3
 - thermion_flutter_platform_interface@0.1.0+2
2024-06-21 15:24:19 +08:00
Nick Fisher
9eb2285433 refactor: rearrange some stubs/imports for easier web WASM deployment 2024-06-21 15:20:08 +08:00
Nick Fisher
c28c518057 chore(release): publish packages
- thermion_flutter@0.1.1+2
2024-06-21 14:09:24 +08:00
Nick Fisher
81ffbdd824 fix: update Flutter example project to use new API
fix: don't keep example project Podfile.lock in repo
2024-06-21 11:46:25 +08:00
Nick Fisher
55b5c7068e fix: add logging dependency to thermion_flutter 2024-06-21 11:30:23 +08:00
62 changed files with 1702 additions and 294 deletions

View File

@@ -3,6 +3,267 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2024-06-26
### Changes
---
Packages with breaking changes:
- [`thermion_dart` - `v0.1.1+2`](#thermion_dart---v0112)
- [`thermion_flutter` - `v0.1.1+7`](#thermion_flutter---v0117)
Packages with other changes:
- [`thermion_flutter_ffi` - `v0.1.0+6`](#thermion_flutter_ffi---v0106)
- [`thermion_flutter_platform_interface` - `v0.1.0+6`](#thermion_flutter_platform_interface---v0106)
- [`thermion_flutter_web` - `v0.0.1+6`](#thermion_flutter_web---v0016)
Packages graduated to a stable release (see pre-releases prior to the stable version for changelog entries):
- `thermion_dart` - `v0.1.1+2`
- `thermion_flutter` - `v0.1.1+7`
- `thermion_flutter_ffi` - `v0.1.0+6`
- `thermion_flutter_platform_interface` - `v0.1.0+6`
- `thermion_flutter_web` - `v0.0.1+6`
---
#### `thermion_dart` - `v0.1.1+2`
#### `thermion_flutter` - `v0.1.1+7`
#### `thermion_flutter_ffi` - `v0.1.0+6`
#### `thermion_flutter_platform_interface` - `v0.1.0+6`
#### `thermion_flutter_web` - `v0.0.1+6`
## 2024-06-26
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.1-dev.0+2`](#thermion_dart---v011-dev02)
- [`thermion_flutter` - `v0.1.1-dev.0+7`](#thermion_flutter---v011-dev07)
- [`thermion_flutter_platform_interface` - `v0.1.0-dev.0+6`](#thermion_flutter_platform_interface---v010-dev06)
- [`thermion_flutter_web` - `v0.0.1-dev.0+6`](#thermion_flutter_web---v001-dev06)
- [`thermion_flutter_ffi` - `v0.1.0-dev.0+6`](#thermion_flutter_ffi---v010-dev06)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `thermion_flutter_platform_interface` - `v0.1.0-dev.0+6`
- `thermion_flutter_web` - `v0.0.1-dev.0+6`
- `thermion_flutter_ffi` - `v0.1.0-dev.0+6`
---
#### `thermion_dart` - `v0.1.1-dev.0+2`
- **FIX**: revert to std::thread (pthreads not easily available on Windows).
- **FIX**: on Windows, pass static libs via -l rather than custom linkWith property so build.dart stays compatible between published & custom versions.
#### `thermion_flutter` - `v0.1.1-dev.0+7`
- **FIX**: add ResourceBuffer header directly to Windows build so I don't have to fiddle around getting the CMake path right.
## 2024-06-22
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.1+1`](#thermion_dart---v0111)
- [`thermion_flutter` - `v0.1.1+6`](#thermion_flutter---v0116)
- [`thermion_flutter_web` - `v0.0.1+5`](#thermion_flutter_web---v0015)
- [`thermion_flutter_platform_interface` - `v0.1.0+5`](#thermion_flutter_platform_interface---v0105)
- [`thermion_flutter_ffi` - `v0.1.0+5`](#thermion_flutter_ffi---v0105)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `thermion_flutter_web` - `v0.0.1+5`
- `thermion_flutter_platform_interface` - `v0.1.0+5`
- `thermion_flutter_ffi` - `v0.1.0+5`
---
#### `thermion_dart` - `v0.1.1+1`
- **DOCS**: update with links to playground.
#### `thermion_flutter` - `v0.1.1+6`
- **DOCS**: update with links to playground.
## 2024-06-21
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.1`](#thermion_dart---v011)
---
#### `thermion_dart` - `v0.1.1`
- Bump "thermion_dart" to `0.1.1`.
## 2024-06-21
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.0+4`](#thermion_dart---v0104)
- [`thermion_flutter_web` - `v0.0.1+4`](#thermion_flutter_web---v0014)
- [`thermion_flutter_platform_interface` - `v0.1.0+4`](#thermion_flutter_platform_interface---v0104)
- [`thermion_flutter` - `v0.1.1+5`](#thermion_flutter---v0115)
- [`thermion_flutter_ffi` - `v0.1.0+4`](#thermion_flutter_ffi---v0104)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `thermion_flutter_web` - `v0.0.1+4`
- `thermion_flutter_platform_interface` - `v0.1.0+4`
- `thermion_flutter` - `v0.1.1+5`
- `thermion_flutter_ffi` - `v0.1.0+4`
---
#### `thermion_dart` - `v0.1.0+4`
- **FIX**: add dummy asset to build.dart on Linux builds so we can use the package on a Linux host.
## 2024-06-21
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.0+3`](#thermion_dart---v0103)
- [`thermion_flutter_web` - `v0.0.1+3`](#thermion_flutter_web---v0013)
- [`thermion_flutter` - `v0.1.1+4`](#thermion_flutter---v0114)
- [`thermion_flutter_platform_interface` - `v0.1.0+3`](#thermion_flutter_platform_interface---v0103)
- [`thermion_flutter_ffi` - `v0.1.0+3`](#thermion_flutter_ffi---v0103)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `thermion_flutter_web` - `v0.0.1+3`
- `thermion_flutter` - `v0.1.1+4`
- `thermion_flutter_platform_interface` - `v0.1.0+3`
- `thermion_flutter_ffi` - `v0.1.0+3`
---
#### `thermion_dart` - `v0.1.0+3`
- **FIX**: exit build.dart early on Linux builds so we can use the package on a Linux host.
## 2024-06-21
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_dart` - `v0.1.0+2`](#thermion_dart---v0102)
- [`thermion_flutter_ffi` - `v0.1.0+2`](#thermion_flutter_ffi---v0102)
- [`thermion_flutter_web` - `v0.0.1+2`](#thermion_flutter_web---v0012)
- [`thermion_flutter` - `v0.1.1+3`](#thermion_flutter---v0113)
- [`thermion_flutter_platform_interface` - `v0.1.0+2`](#thermion_flutter_platform_interface---v0102)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `thermion_flutter_web` - `v0.0.1+2`
- `thermion_flutter` - `v0.1.1+3`
- `thermion_flutter_platform_interface` - `v0.1.0+2`
---
#### `thermion_dart` - `v0.1.0+2`
- **REFACTOR**: rearrange some stubs/imports for easier web WASM deployment.
#### `thermion_flutter_ffi` - `v0.1.0+2`
- **REFACTOR**: rearrange some stubs/imports for easier web WASM deployment.
## 2024-06-21
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`thermion_flutter` - `v0.1.1+2`](#thermion_flutter---v0112)
---
#### `thermion_flutter` - `v0.1.1+2`
- **FIX**: update Flutter example project to use new API.
- **FIX**: add logging dependency to thermion_flutter.
## 2024-06-21
### Changes

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2024 Nick Fisher
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -4,6 +4,7 @@
<a href="https://docs.page/nmfisher/thermion/quickstart">Quickstart (Flutter)</a> •
<a href="https://docs.page/nmfisher/thermion">Documentation</a> •
<a href="https://docs.page/nmfisher/thermion/examples">Showcase</a> •
<a href="https://dartpad.thermion.dev/">Playground</a> •
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
</p>

View File

@@ -7,10 +7,15 @@
"Getting Started",
[
["Overview", "/"],
["Quick Start", "/quickstart"]
["Quick Start", "/quickstart"],
["Playground", "https://dartpad.thermion.dev"]
]
],
["Misc.", [["Contributing", "/contributing"]]]
["Misc.", [
["Windows", "/windows"],
["Android", "/android"],
["Contributing", "/contributing"]
]]
]
}

View File

@@ -4,3 +4,7 @@ Thermion is an open source project and we welcome all contributions from every l
Please [join us on Discord](https://discord.gg/h2VdDK3EAQ) if you'd like some guidance or just want to chat.
##
We are now using [Melos](https://melos.invertase.dev/) to manage the repository. This lets us auto-generate changelogs & versioning from commit messages, so if you wish to submit a PR, please use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -204,6 +204,8 @@ The cube still won't be visible until we add a light to the scene and tell Therm
$ flutter run -d macos
```
> You may experience a noticeable delay the very first time you run the project. Don't panic, it's not frozen! This is due to the build system downloading the prebuilt Filament binaries from Cloudflare, which can take some time (particularly on Windows). These binaries will be cached after first download, so subsequent runs will be much faster (though every time you run flutter clean, the binaries will be re-downloaded).
![Screenshot of Thermion Quickstart project](images/thermion_sample_project.png)
Your first Thermion project is complete!

View File

@@ -1,15 +1,29 @@
## Windows
## CMakeLists
You will need to disable the `/WX` compiler flag.
In your project, open the `windows/CMakeList.txt` file and find the following line:
`target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")`
Delete the `/WX`:
`target_compile_options(${TARGET} PRIVATE /W4 /wd"4100")`
## pubspec.yaml
On Windows, you will need to add a custom version of `native_toolchain_c` to your `dependency_overrides`. This is currently needed to link static libraries when building a DLL.
```
native_toolchain_c:
dependency_overrides:
native_toolchain_c:
git:
url: git@github.com:nmfisher/native.git
url: https://github.com/nmfisher/native.git
path: pkgs/native_toolchain_c
ref: 99020084c4687be4c58c7115a167088c0441d1de
ref: windows_dll_fix
```
This will eventually be fixed upstream in the `native_toolchain_c` package, so this should be a short-term/temporary issue only.

View File

@@ -1,36 +1,34 @@
import 'package:flutter/widgets.dart';
import 'package:thermion_flutter/filament/widgets/camera/entity_controller_mouse_widget.dart';
import 'package:thermion_flutter/filament/widgets/camera/gestures/filament_gesture_detector.dart';
import 'package:thermion_flutter/filament/widgets/filament_widget.dart';
import 'package:thermion_flutter/thermion/widgets/camera/entity_controller_mouse_widget.dart';
import 'package:thermion_flutter/thermion_flutter.dart';
import 'package:thermion_dart/thermion_dart/entities/entity_transform_controller.dart';
class ExampleViewport extends StatelessWidget {
final ThermionFlutterPlugin? controller;
final ThermionViewer? viewer;
final EntityTransformController? entityTransformController;
final EdgeInsets padding;
final FocusNode keyboardFocusNode;
const ExampleViewport(
{super.key,
required this.controller,
required this.viewer,
required this.padding,
required this.keyboardFocusNode,
this.entityTransformController});
@override
Widget build(BuildContext context) {
return controller != null
return viewer != null
? Padding(
padding: padding,
child: EntityTransformMouseControllerWidget(
transformController: entityTransformController,
child: FilamentGestureDetector(
child: ThermionGestureDetector(
showControlOverlay: true,
controller: controller!.viewer,
controller: viewer!,
child: ThermionWidget(
plugin: controller!,
viewer: viewer!,
))))
: Container();
}

View File

@@ -1,14 +1,10 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:thermion_flutter/filament/widgets/debug/entity_list_widget.dart';
import 'package:thermion_flutter_example/camera_matrix_overlay.dart';
import 'package:thermion_flutter/thermion/widgets/debug/entity_list_widget.dart';
import 'package:thermion_flutter_example/menus/controller_menu.dart';
import 'package:thermion_flutter_example/example_viewport.dart';
import 'package:thermion_dart/thermion_dart/entities/entity_transform_controller.dart';
import 'package:thermion_flutter_example/menus/scene_menu.dart';
import 'package:thermion_flutter/thermion_flutter.dart';
import 'package:thermion_flutter_example/picker_result_widget.dart';
const loadDefaultScene = bool.hasEnvironment('--load-default-scene');
@@ -38,8 +34,7 @@ class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
bodyMedium: TextStyle(fontSize: 12))),
// showPerformanceOverlay: true,
home: const Scaffold(
backgroundColor: Color(0x00000000),
body: ExampleWidget()));
backgroundColor: Color(0x00000000), body: ExampleWidget()));
}
}
@@ -55,7 +50,7 @@ class ExampleWidget extends StatefulWidget {
enum MenuType { controller, assets, camera, misc }
class ExampleWidgetState extends State<ExampleWidget> {
final _plugin = ThermionFlutterPlugin();
ThermionViewer? _viewer;
EdgeInsets _viewportMargin = EdgeInsets.zero;
@@ -99,105 +94,103 @@ class ExampleWidgetState extends State<ExampleWidget> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _plugin.initialized,
builder: (_, AsyncSnapshot<bool> initialized) {
var isInitialized = initialized.data == true;
return Stack(
fit: StackFit.expand,
children: [
if (isInitialized)
Positioned.fill(
child: ExampleViewport(
controller: isInitialized ? _plugin : null,
entityTransformController: _transformController,
padding: _viewportMargin,
keyboardFocusNode: _sharedFocusNode),
return Stack(fit: StackFit.expand, children: [
if (_viewer != null)
Positioned.fill(
child: ExampleViewport(
viewer: _viewer!,
entityTransformController: _transformController,
padding: _viewportMargin,
keyboardFocusNode: _sharedFocusNode),
),
Positioned(
bottom: 30,
left: 0,
right: 10,
height: 30,
child: Container(
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white.withOpacity(0.25),
),
Positioned(
bottom: 30,
left: 0,
right: 10,
height: 30,
child: Container(
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white.withOpacity(0.25),
),
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ControllerMenu(
sharedFocusNode: _sharedFocusNode,
controller: _plugin,
onToggleViewport: () {
setState(() {
_viewportMargin =
(_viewportMargin == EdgeInsets.zero)
? const EdgeInsets.all(30)
: EdgeInsets.zero;
});
},
onControllerDestroyed: () {},
onControllerCreated: () {}),
SceneMenu(
sharedFocusNode: _sharedFocusNode,
controller: _plugin,
),
GestureDetector(
onTap: () async {
await _plugin.viewer.loadGlb(
'assets/shapes/shapes.glb',
numInstances: 1);
},
child: Container(
color: Colors.transparent,
child: const Text("shapes.glb"))),
const SizedBox(width: 5),
GestureDetector(
onTap: () async {
await _plugin.viewer.loadGlb('assets/1.glb');
},
child: Container(
color: Colors.transparent,
child: const Text("1.glb"))),
const SizedBox(width: 5),
GestureDetector(
onTap: () async {
await _plugin.viewer.loadGlb('assets/2.glb');
},
child: Container(
color: Colors.transparent,
child: const Text("2.glb"))),
const SizedBox(width: 5),
GestureDetector(
onTap: () async {
await _plugin.viewer.loadGlb('assets/3.glb');
},
child: Container(
color: Colors.transparent,
child: const Text("3.glb"))),
Expanded(child: Container()),
]))),
if (isInitialized) ...[
Positioned(top:10, left:10, width:200, height:200, child:Container(
child:EntityListWidget(controller: _plugin.viewer))),
// Padding(
// padding: const EdgeInsets.only(top: 10, left: 20, right: 20),
// child: ValueListenableBuilder(
// valueListenable: showProjectionMatrices,
// builder: (ctx, value, child) => CameraMatrixOverlay(
// controller: _plugin.viewer, showProjectionMatrices: value)),
// ),
// Align(
// alignment: Alignment.topRight,
// child: PickerResultWidget(controller: _plugin.viewer),
// )
]
]);
});
padding: const EdgeInsets.symmetric(horizontal: 10),
child:
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
ViewerMenu(
sharedFocusNode: _sharedFocusNode,
viewer: _viewer,
onToggleViewport: () {
setState(() {
_viewportMargin = (_viewportMargin == EdgeInsets.zero)
? const EdgeInsets.all(30)
: EdgeInsets.zero;
});
},
onViewerDestroyed: () {
setState(() {
_viewer = null;
});
},
onViewerCreated: (v) {
setState(() {
_viewer = v;
});
}),
SceneMenu(
sharedFocusNode: _sharedFocusNode,
controller: _viewer,
),
GestureDetector(
onTap: () async {
await _viewer!
.loadGlb('assets/shapes/shapes.glb', numInstances: 1);
},
child: Container(
color: Colors.transparent,
child: const Text("shapes.glb"))),
const SizedBox(width: 5),
GestureDetector(
onTap: () async {
await _viewer!.loadGlb('assets/1.glb');
},
child: Container(
color: Colors.transparent, child: const Text("1.glb"))),
const SizedBox(width: 5),
GestureDetector(
onTap: () async {
await _viewer!.loadGlb('assets/2.glb');
},
child: Container(
color: Colors.transparent, child: const Text("2.glb"))),
const SizedBox(width: 5),
GestureDetector(
onTap: () async {
await _viewer!.loadGlb('assets/3.glb');
},
child: Container(
color: Colors.transparent, child: const Text("3.glb"))),
Expanded(child: Container()),
]))),
if (_viewer != null) ...[
Positioned(
top: 10,
left: 10,
width: 200,
height: 200,
child: Container(child: EntityListWidget(controller: _viewer!))),
// Padding(
// padding: const EdgeInsets.only(top: 10, left: 20, right: 20),
// child: ValueListenableBuilder(
// valueListenable: showProjectionMatrices,
// builder: (ctx, value, child) => CameraMatrixOverlay(
// controller: _viewer!, showProjectionMatrices: value)),
// ),
// Align(
// alignment: Alignment.topRight,
// child: PickerResultWidget(controller: _viewer!),
// )
]
]);
}
}

View File

@@ -8,8 +8,8 @@ import 'package:vector_math/vector_math_64.dart' as v;
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
class AssetSubmenu extends StatefulWidget {
final ThermionFlutterPlugin controller;
const AssetSubmenu({super.key, required this.controller});
final ThermionViewer viewer;
const AssetSubmenu({super.key, required this.viewer});
@override
State<StatefulWidget> createState() => _AssetSubmenuState();
@@ -26,8 +26,8 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
MenuItemButton(
closeOnActivate: false,
onPressed: () async {
var entity = await widget.controller.viewer.getChildEntity(
widget.controller.viewer.scene.listEntities().last, "Cylinder");
var entity = await widget.viewer.getChildEntity(
widget.viewer.scene.listEntities().last, "Cylinder");
await showDialog(
context: context,
builder: (BuildContext context) {
@@ -39,8 +39,8 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
child: const Text('Find Cylinder entity by name')),
MenuItemButton(
onPressed: () async {
widget.controller.viewer.setPosition(
widget.controller.viewer.scene.listEntities().last,
widget.viewer.setPosition(
widget.viewer.scene.listEntities().last,
1.0,
1.0,
-1.0);
@@ -50,8 +50,8 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
MenuItemButton(
onPressed: () async {
final color = Colors.purple;
widget.controller.viewer.setMaterialColor(
widget.controller.viewer.scene.listEntities().last,
widget.viewer.setMaterialColor(
widget.viewer.scene.listEntities().last,
"Cone",
0,
color.red / 255.0,
@@ -85,14 +85,14 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
-1.0,
];
var indices = [0, 1, 2, 2, 3, 0];
var geom = await widget.controller.viewer.createGeometry(
var geom = await widget.viewer.createGeometry(
verts, indices,
materialPath: "asset://assets/solidcolor.filamat");
},
child: const Text("Quad")),
MenuItemButton(
onPressed: () async {
await widget.controller.viewer.createGeometry([
await widget.viewer.createGeometry([
0,
0,
0,
@@ -118,14 +118,14 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
_geometrySubmenu(),
MenuItemButton(
onPressed: () async {
await widget.controller.viewer.addLight(
await widget.viewer.addLight(
LightType.DIRECTIONAL, 6500, 100000, 0, 1, 0, 0, -1, 0);
},
child: const Text("Add directional light"),
),
MenuItemButton(
onPressed: () async {
await widget.controller.viewer.addLight(
await widget.viewer.addLight(
LightType.POINT, 6500, 100000, 0, 1, 0, 0, -1, 0,
falloffRadius: 1.0);
},
@@ -133,7 +133,7 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
),
MenuItemButton(
onPressed: () async {
await widget.controller.viewer.addLight(
await widget.viewer.addLight(
LightType.SPOT, 6500, 1000000, 0, 0, 0, 0, 1, 0,
spotLightConeInner: 0.1,
spotLightConeOuter: 0.4,
@@ -143,26 +143,26 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
),
MenuItemButton(
onPressed: () async {
await widget.controller.viewer.clearLights();
await widget.viewer.clearLights();
},
child: const Text("Clear lights"),
),
MenuItemButton(
onPressed: () {
final color = const Color(0xAA73C9FA);
widget.controller.viewer.setBackgroundColor(color.red / 255.0,
widget.viewer.setBackgroundColor(color.red / 255.0,
color.green / 255.0, color.blue / 255.0, 1.0);
},
child: const Text("Set background color")),
MenuItemButton(
onPressed: () {
widget.controller.viewer
widget.viewer
.setBackgroundImage('assets/background.ktx');
},
child: const Text("Load background image")),
MenuItemButton(
onPressed: () {
widget.controller.viewer.setBackgroundImage(
widget.viewer.setBackgroundImage(
'assets/background.ktx',
fillHeight: true);
},
@@ -170,9 +170,9 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
MenuItemButton(
onPressed: () {
if (ExampleWidgetState.hasSkybox) {
widget.controller.viewer.removeSkybox();
widget.viewer.removeSkybox();
} else {
widget.controller.viewer
widget.viewer
.loadSkybox('assets/default_env/default_env_skybox.ktx');
}
ExampleWidgetState.hasSkybox = !ExampleWidgetState.hasSkybox;
@@ -182,18 +182,18 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
: 'Load skybox')),
MenuItemButton(
onPressed: () {
widget.controller.viewer
widget.viewer
.loadIbl('assets/default_env/default_env_ibl.ktx');
},
child: const Text('Load IBL')),
MenuItemButton(
onPressed: () {
widget.controller.viewer.removeIbl();
widget.viewer.removeIbl();
},
child: const Text('Remove IBL')),
MenuItemButton(
onPressed: () async {
await widget.controller.viewer.clearEntities();
await widget.viewer.clearEntities();
},
child: const Text('Clear assets')),
],

View File

@@ -8,8 +8,8 @@ import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:thermion_flutter_example/main.dart';
class CameraSubmenu extends StatefulWidget {
final ThermionFlutterPlugin controller;
const CameraSubmenu({super.key, required this.controller});
final ThermionViewer viewer;
const CameraSubmenu({super.key, required this.viewer});
@override
State<StatefulWidget> createState() => _CameraSubmenuState();
@@ -22,10 +22,10 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
@override
void initState() {
super.initState();
widget.controller.viewer.initialized.then((_) {
widget.controller.viewer.getCameraCullingNear().then((v) {
widget.viewer.initialized.then((_) {
widget.viewer.getCameraCullingNear().then((v) {
_near = v;
widget.controller.viewer.getCameraCullingFar().then((v) {
widget.viewer.getCameraCullingFar().then((v) {
_far = v;
setState(() {});
});
@@ -56,7 +56,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
menuChildren: [1.0, 7.0, 14.0, 28.0, 56.0]
.map((v) => MenuItemButton(
onPressed: () {
widget.controller.viewer.setCameraFocalLength(v);
widget.viewer.setCameraFocalLength(v);
},
child: Text(
v.toStringAsFixed(2),
@@ -71,7 +71,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
_near = v;
print("Setting camera culling to $_near $_far!");
widget.controller.viewer.setCameraCulling(_near!, _far!);
widget.viewer.setCameraCulling(_near!, _far!);
},
child: Text(
v.toStringAsFixed(2),
@@ -85,7 +85,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
onPressed: () {
_far = v;
print("Setting camera culling to $_near! $_far");
widget.controller.viewer.setCameraCulling(_near!, _far!);
widget.viewer.setCameraCulling(_near!, _far!);
},
child: Text(
v.toStringAsFixed(2),
@@ -95,21 +95,21 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
child: const Text("Set far")),
MenuItemButton(
onPressed: () async {
widget.controller.viewer.setCameraPosition(1.0, 1.0, -1.0);
widget.viewer.setCameraPosition(1.0, 1.0, -1.0);
},
child: const Text('Set position to 1, 1, -1 (leave rotation as-is)'),
),
MenuItemButton(
onPressed: () async {
widget.controller.viewer.setCameraPosition(0.0, 0.0, 0.0);
widget.controller.viewer.setCameraRotation(
widget.viewer.setCameraPosition(0.0, 0.0, 0.0);
widget.viewer.setCameraRotation(
v.Quaternion.axisAngle(v.Vector3(0, 0.0, 1.0), 0.0));
},
child: const Text('Move to 0,0,0, facing towards 0,0,-1'),
),
MenuItemButton(
onPressed: () {
widget.controller.viewer.setCameraRotation(
widget.viewer.setCameraRotation(
v.Quaternion.axisAngle(v.Vector3(0, 1, 0), pi / 4));
},
child: const Text("Rotate camera 45 degrees around y axis"),
@@ -118,7 +118,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
onPressed: () {
ExampleWidgetState.frustumCulling =
!ExampleWidgetState.frustumCulling;
widget.controller.viewer
widget.viewer
.setViewFrustumCulling(ExampleWidgetState.frustumCulling);
},
child: Text(
@@ -128,7 +128,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
closeOnActivate: false,
onPressed: () async {
var projMatrix =
await widget.controller.viewer.getCameraProjectionMatrix();
await widget.viewer.getCameraProjectionMatrix();
await showDialog(
context: context,
builder: (ctx) {
@@ -147,7 +147,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
menuChildren: ManipulatorMode.values.map((mm) {
return MenuItemButton(
onPressed: () {
widget.controller.viewer.setCameraManipulatorOptions(
widget.viewer.setCameraManipulatorOptions(
mode: mm,
orbitSpeedX: ExampleWidgetState.orbitSpeedX,
orbitSpeedY: ExampleWidgetState.orbitSpeedY,
@@ -169,7 +169,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
return MenuItemButton(
onPressed: () {
ExampleWidgetState.zoomSpeed = speed;
widget.controller.viewer.setCameraManipulatorOptions(
widget.viewer.setCameraManipulatorOptions(
orbitSpeedX: ExampleWidgetState.orbitSpeedX,
orbitSpeedY: ExampleWidgetState.orbitSpeedY,
zoomSpeed: ExampleWidgetState.zoomSpeed);
@@ -191,7 +191,7 @@ class _CameraSubmenuState extends State<CameraSubmenu> {
onPressed: () {
ExampleWidgetState.orbitSpeedX = speed;
ExampleWidgetState.orbitSpeedY = speed;
widget.controller.viewer.setCameraManipulatorOptions(
widget.viewer.setCameraManipulatorOptions(
orbitSpeedX: ExampleWidgetState.orbitSpeedX,
orbitSpeedY: ExampleWidgetState.orbitSpeedY,
zoomSpeed: ExampleWidgetState.zoomSpeed);

View File

@@ -5,29 +5,31 @@ import 'package:flutter/widgets.dart';
import 'package:thermion_flutter/thermion_flutter.dart';
class ControllerMenu extends StatefulWidget {
final ThermionFlutterPlugin controller;
class ViewerMenu extends StatefulWidget {
final ThermionViewer? viewer;
final void Function() onToggleViewport;
final void Function() onControllerCreated;
final void Function() onControllerDestroyed;
final void Function(ThermionViewer viewer) onViewerCreated;
final void Function() onViewerDestroyed;
final FocusNode sharedFocusNode;
ControllerMenu(
{required this.controller,
required this.onControllerCreated,
required this.onControllerDestroyed,
ViewerMenu(
{
required this.viewer,
required this.onViewerCreated,
required this.onViewerDestroyed,
required this.sharedFocusNode,
required this.onToggleViewport});
@override
State<StatefulWidget> createState() => _ControllerMenuState();
State<StatefulWidget> createState() => _ViewerMenuState();
}
class _ControllerMenuState extends State<ControllerMenu> {
void _createController({String? uberArchivePath}) async {
widget.controller.initialize(uberArchivePath: uberArchivePath);
widget.onControllerCreated();
class _ViewerMenuState extends State<ViewerMenu> {
void _createViewer({String? uberArchivePath}) async {
var viewer = await ThermionFlutterPlugin.createViewer(
uberArchivePath: uberArchivePath);
await viewer.initialized;
widget.onViewerCreated(viewer);
}
@override
@@ -36,7 +38,7 @@ class _ControllerMenuState extends State<ControllerMenu> {
}
@override
void didUpdateWidget(ControllerMenu oldWidget) {
void didUpdateWidget(ViewerMenu oldWidget) {
super.didUpdateWidget(oldWidget);
}
@@ -50,14 +52,14 @@ class _ControllerMenuState extends State<ControllerMenu> {
child:
const Text("Create ThermionFlutterPlugin (default ubershader)"),
onPressed: () {
_createController();
_createViewer();
},
),
MenuItemButton(
child: const Text(
"Create ThermionFlutterPlugin (custom ubershader - lit opaque only)"),
onPressed: () {
_createController(
_createViewer(
uberArchivePath: Platform.isWindows
? "assets/lit_opaque_32.uberz"
: Platform.isMacOS
@@ -73,8 +75,8 @@ class _ControllerMenuState extends State<ControllerMenu> {
MenuItemButton(
child: const Text("Destroy viewer"),
onPressed: () async {
widget.controller.dispose();
widget.onControllerDestroyed();
widget.viewer!.dispose();
widget.onViewerDestroyed();
setState(() {});
},
)
@@ -89,8 +91,7 @@ class _ControllerMenuState extends State<ControllerMenu> {
onPressed: widget.onToggleViewport,
)
],
builder:
(BuildContext context, MenuController controller, Widget? child) {
builder: (BuildContext context, MenuController controller, Widget? child) {
return TextButton(
onPressed: () {
if (controller.isOpen) {
@@ -99,7 +100,7 @@ class _ControllerMenuState extends State<ControllerMenu> {
controller.open();
}
},
child: const Text("Controller / Viewer"),
child: const Text("Viewer / Viewer"),
);
});
}

View File

@@ -4,9 +4,9 @@ import 'package:thermion_flutter_example/main.dart';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
class RenderingSubmenu extends StatefulWidget {
final ThermionFlutterPlugin controller;
final ThermionViewer viewer;
const RenderingSubmenu({super.key, required this.controller});
const RenderingSubmenu({super.key, required this.viewer});
@override
State<StatefulWidget> createState() => _RenderingSubmenuState();
@@ -19,14 +19,14 @@ class _RenderingSubmenuState extends State<RenderingSubmenu> {
menuChildren: [
MenuItemButton(
onPressed: () {
widget.controller.viewer.render();
widget.viewer.render();
},
child: const Text("Render single frame"),
),
MenuItemButton(
onPressed: () {
ExampleWidgetState.rendering = !ExampleWidgetState.rendering;
widget.controller.viewer.setRendering(ExampleWidgetState.rendering);
widget.viewer.setRendering(ExampleWidgetState.rendering);
},
child: Text(
"Set continuous rendering to ${!ExampleWidgetState.rendering}"),
@@ -35,14 +35,14 @@ class _RenderingSubmenuState extends State<RenderingSubmenu> {
onPressed: () {
ExampleWidgetState.framerate =
ExampleWidgetState.framerate == 60 ? 30 : 60;
widget.controller.viewer.setFrameRate(ExampleWidgetState.framerate);
widget.viewer.setFrameRate(ExampleWidgetState.framerate);
},
child: Text(
"Toggle framerate (currently ${ExampleWidgetState.framerate}) "),
),
MenuItemButton(
onPressed: () {
widget.controller.viewer.setToneMapping(ToneMapper.LINEAR);
widget.viewer.setToneMapping(ToneMapper.LINEAR);
},
child: const Text("Set tone mapping to linear"),
),
@@ -50,7 +50,7 @@ class _RenderingSubmenuState extends State<RenderingSubmenu> {
onPressed: () {
ExampleWidgetState.postProcessing =
!ExampleWidgetState.postProcessing;
widget.controller.viewer
widget.viewer
.setPostProcessing(ExampleWidgetState.postProcessing);
},
child: Text(
@@ -60,7 +60,7 @@ class _RenderingSubmenuState extends State<RenderingSubmenu> {
onPressed: () {
ExampleWidgetState.antiAliasingMsaa =
!ExampleWidgetState.antiAliasingMsaa;
widget.controller.viewer.setAntiAliasing(
widget.viewer.setAntiAliasing(
ExampleWidgetState.antiAliasingMsaa,
ExampleWidgetState.antiAliasingFxaa,
ExampleWidgetState.antiAliasingTaa);
@@ -72,7 +72,7 @@ class _RenderingSubmenuState extends State<RenderingSubmenu> {
onPressed: () {
ExampleWidgetState.antiAliasingFxaa =
!ExampleWidgetState.antiAliasingFxaa;
widget.controller.viewer.setAntiAliasing(
widget.viewer.setAntiAliasing(
ExampleWidgetState.antiAliasingMsaa,
ExampleWidgetState.antiAliasingFxaa,
ExampleWidgetState.antiAliasingTaa);
@@ -83,7 +83,7 @@ class _RenderingSubmenuState extends State<RenderingSubmenu> {
MenuItemButton(
onPressed: () {
ExampleWidgetState.recording = !ExampleWidgetState.recording;
widget.controller.viewer.setRecording(ExampleWidgetState.recording);
widget.viewer.setRecording(ExampleWidgetState.recording);
},
child: Text(
"Turn recording ${ExampleWidgetState.recording ? "OFF" : "ON"}) "),

View File

@@ -6,7 +6,7 @@ import 'package:thermion_flutter_example/menus/camera_submenu.dart';
import 'package:thermion_flutter_example/menus/rendering_submenu.dart';
class SceneMenu extends StatefulWidget {
final ThermionFlutterPlugin? controller;
final ThermionViewer? controller;
final FocusNode sharedFocusNode;
const SceneMenu(
@@ -37,11 +37,11 @@ class _SceneMenuState extends State<SceneMenu> {
? []
: <Widget>[
RenderingSubmenu(
controller: widget.controller!,
viewer: widget.controller!,
),
AssetSubmenu(controller: widget.controller!),
AssetSubmenu(viewer: widget.controller!),
CameraSubmenu(
controller: widget.controller!,
viewer: widget.controller!,
),
],
builder:

View File

@@ -1,29 +0,0 @@
PODS:
- FlutterMacOS (1.0.0)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- thermion_flutter (0.0.1):
- FlutterMacOS
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- thermion_flutter (from `Flutter/ephemeral/.symlinks/plugins/thermion_flutter/macos`)
EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
thermion_flutter:
:path: Flutter/ephemeral/.symlinks/plugins/thermion_flutter/macos
SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
thermion_flutter: e4895ade6b14d9efb6e17ed2436e89dbb87fa998
PODFILE CHECKSUM: 1888651be91a8ad58692c1add9ce24279fd4e950
COCOAPODS: 1.15.2

View File

@@ -13,9 +13,22 @@ dependencies:
sdk: flutter
path_provider:
thermion_flutter:
path: ../../../thermion_flutter/thermion_flutter
cupertino_icons: ^1.0.2
web:
dependency_overrides:
thermion_flutter:
path: ../../../thermion_flutter/thermion_flutter
thermion_flutter_platform_interface:
path: ../../../thermion_flutter/thermion_flutter_platform_interface
thermion_flutter_ffi:
path: ../../../thermion_flutter/thermion_flutter_ffi
thermion_flutter_web:
path: ../../../thermion_flutter/thermion_flutter_web
thermion_dart:
path: ../../../thermion_dart
dev_dependencies:
flutter_test:
sdk: flutter

View File

@@ -1,5 +1,4 @@
name: thermion_workspace
packages:
- thermion_dart
- thermion_flutter/**

View File

@@ -1,3 +1,32 @@
## 0.1.1+2
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 0.1.1-dev.0+2
- **FIX**: revert to std::thread (pthreads not easily available on Windows).
- **FIX**: on Windows, pass static libs via -l rather than custom linkWith property so build.dart stays compatible between published & custom versions.
## 0.1.1+1
- **DOCS**: update with links to playground.
## 0.1.1
- Bump "thermion_dart" to `0.1.1`.
## 0.1.0+4
- **FIX**: add dummy asset to build.dart on Linux builds so we can use the package on a Linux host.
## 0.1.0+3
- **FIX**: exit build.dart early on Linux builds so we can use the package on a Linux host.
## 0.1.0+2
- **REFACTOR**: rearrange some stubs/imports for easier web WASM deployment.
## 0.1.0+1
- **REFACTOR**: export ThermionViewerWasm for web and hide FFI/WASM version.

View File

@@ -4,6 +4,7 @@
<a href="https://docs.page/nmfisher/flutter_filament/quickstart">Quickstart (Flutter)</a> •
<a href="https://docs.page/nmfisher/flutter_filament">Documentation</a> •
<a href="https://github.com/nmfisher/thermion/docs/examples/">Showcase</a> •
<a href="https://dartpad.thermion.dev/">Playground</a> •
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
</p>

View File

@@ -22,6 +22,32 @@ void main(List<String> args) async {
var platform = config.targetOS.toString().toLowerCase();
// We don't support Linux (yet), so the native/Filament libraries won't be
// compiled/available. However, we still want to be able to run the Dart
// package itself on a Linux host(e.g. for dart_services backed), so if
// we detect that we're running on Linux, add some dummy native code
// assets and exit early.
if (platform == "linux") {
final linkMode = DynamicLoadingBundled();
final name = "thermion_dart.dart";
final libUri = config.outputDirectory
.resolve(config.targetOS.libraryFileName(name, linkMode));
output.addAssets(
[
NativeCodeAsset(
package: config.packageName,
name: name,
file: libUri,
linkMode: linkMode,
os: config.targetOS,
architecture: config.dryRun ? null : config.targetArchitecture,
)
],
linkInPackage: null,
);
return;
}
var libDir = config.dryRun ? "" : (await getLibDir(config, logger)).path;
final packageName = config.packageName;
@@ -36,7 +62,7 @@ void main(List<String> args) async {
"${config.packageRoot.toFilePath()}/native/include/material/image.c",
]);
final libs = [
var libs = [
"filament",
"backend",
"filameshio",
@@ -65,12 +91,12 @@ void main(List<String> args) async {
"basis_transcoder"
];
final linkWith = <String>[];
if (platform == "windows") {
linkWith.addAll(libs.map((lib) => "$libDir/$lib.lib"));
linkWith.addAll(["$libDir/bluevk.lib", "$libDir/bluegl.lib"]);
linkWith.addAll([
libDir = Directory(libDir).uri.toFilePath();
libs = libs.map((lib) => "${libDir}${lib}.lib").toList();
libs.addAll(["${libDir}bluevk.lib", "${libDir}bluegl.lib"]);
libs.addAll([
"gdi32.lib",
"user32.lib",
"shell32.lib",
@@ -81,7 +107,7 @@ void main(List<String> args) async {
} else {
libs.add("stdc++");
}
final flags = []; //"-fsanitize=address"];
final flags = []; //"-fsanitize=address"];
final defines = <String, String?>{};
var frameworks = [];
@@ -125,14 +151,12 @@ void main(List<String> args) async {
sources: sources,
includes: ['native/include', 'native/include/filament'],
defines: defines,
// UNCOMMENT THIS IF YOU ARE BUILDING WITH THE CUSTOM native_toolchain_c FORK FOR WINDOWS
// linkWith: linkWith,
flags: [
if (platform == "macos") '-mmacosx-version-min=13.0',
if (platform == "ios") '-mios-version-min=13.0',
...flags,
...frameworks,
if (platform != "windows") ...libs.map((lib) => "-l$lib"),
...libs.map((lib) => "-l$lib"),
"-L$libDir",
],
dartBuildFiles: ['hook/build.dart'],

View File

@@ -1,5 +1,8 @@
library filament_dart;
export 'thermion_dart/thermion_viewer.dart';
export 'thermion_dart/compatibility/web/interop/thermion_viewer_wasm.dart' if (dart.library.io) 'thermion_dart/thermion_viewer_ffi.dart';
export 'thermion_dart/thermion_viewer_stub.dart'
if (dart.library.io) 'thermion_dart/thermion_viewer_ffi.dart'
if (dart.library.js_interop)'thermion_dart/compatibility/web/interop/thermion_viewer_wasm.dart';
export 'thermion_dart/entities/entity_transform_controller.dart';

View File

@@ -1,3 +1 @@
export 'web/compatibility.dart' if (dart.library.io) 'native/compatibility.dart';
export 'native/compatibility.dart';

View File

@@ -6,7 +6,7 @@ import 'dart:convert';
import 'dart:ffi' as ffi hide Uint8Pointer, FloatPointer;
import 'dart:typed_data';
import 'package:thermion_dart/thermion_dart/compatibility/web/thermion_dart.g.dart';
import 'package:thermion_dart/thermion_dart/compatibility/web/ffi/thermion_dart.g.dart';
import 'package:ffi/ffi.dart';
export 'package:ffi/ffi.dart' hide StringUtf8Pointer, Utf8Pointer;

View File

@@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:js_interop';
import 'package:thermion_dart/thermion_dart/compatibility/web/interop.dart';
import 'package:thermion_dart/thermion_dart/compatibility/web/ffi/interop.dart';
import "allocator.dart";

View File

@@ -33,8 +33,11 @@ extension type _EmscriptenModule(JSObject _) implements JSObject {
external JSAny get HEAP32;
}
typedef ThermionViewerImpl = ThermionViewerWasm;
///
/// An [ThermionViewer] implementation that forwards calls to
/// A [ThermionViewer] implementation that forwards calls to
/// the (Emscripten-generated) ThermionDart JS module.
///
class ThermionViewerWasm implements ThermionViewer {
@@ -43,8 +46,8 @@ class ThermionViewerWasm implements ThermionViewer {
bool _initialized = false;
bool _rendering = false;
ThermionViewerWasm({String moduleName = "thermion_dart"}) {
_module = window.getProperty<_EmscriptenModule>(moduleName.toJS);
ThermionViewerWasm({JSObject? module, String moduleName = "thermion_dart"}) {
_module = module as _EmscriptenModule? ?? window.getProperty<_EmscriptenModule>(moduleName.toJS);
}
JSNumber? _viewer;
@@ -1687,7 +1690,7 @@ class ThermionViewerWasm implements ThermionViewer {
Future setMorphTargetWeights(
ThermionEntity entity, List<double> weights) async {
final numWeights = weights.length;
final ptr = _module._malloc(numWeights * 4) as JSNumber;
final ptr = _module._malloc(numWeights * 4);
for (int i = 0; i < numWeights; i++) {
_module.setValue(
(ptr.toDartInt + (i * 4)).toJS, weights[i].toJS, "float");

View File

@@ -47,6 +47,7 @@ class TextureDetails {
}
abstract class ThermionViewer {
Future<bool> get initialized;
///

View File

@@ -9,6 +9,8 @@ import 'thermion_viewer.dart';
import 'scene_impl.dart';
import 'package:logging/logging.dart';
typedef ThermionViewerImpl = ThermionViewerFFI;
// ignore: constant_identifier_names
const ThermionEntity _FILAMENT_ASSET_ERROR = 0;
@@ -16,7 +18,6 @@ typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
class ThermionViewerFFI extends ThermionViewer {
final _logger = Logger("ThermionViewerFFI");
final _compat = Compatibility();
SceneImpl? _scene;
Scene get scene => _scene!;

View File

@@ -0,0 +1,729 @@
import 'dart:math';
import 'package:thermion_dart/thermion_dart/scene.dart';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:vector_math/vector_math_64.dart';
import 'dart:async';
import 'package:animation_tools_dart/animation_tools_dart.dart';
typedef ThermionViewerImpl = ThermionViewerStub;
class ThermionViewerStub extends ThermionViewer {
@override
Future addAnimationComponent(ThermionEntity entity) {
// TODO: implement addAnimationComponent
throw UnimplementedError();
}
@override
Future addBoneAnimation(ThermionEntity entity, BoneAnimationData animation,
{int skinIndex = 0,
double fadeInInSecs = 0.0,
double fadeOutInSecs = 0.0,
double maxDelta = 1.0}) {
// TODO: implement addBoneAnimation
throw UnimplementedError();
}
@override
Future addCollisionComponent(ThermionEntity entity,
{void Function(int entityId1, int entityId2)? callback,
bool affectsTransform = false}) {
// TODO: implement addCollisionComponent
throw UnimplementedError();
}
@override
Future<ThermionEntity> addLight(
LightType type,
double colour,
double intensity,
double posX,
double posY,
double posZ,
double dirX,
double dirY,
double dirZ,
{double falloffRadius = 1.0,
double spotLightConeInner = pi / 8,
double spotLightConeOuter = pi / 4,
double sunAngularRadius = 0.545,
double sunHaloSize = 10.0,
double sunHaloFallof = 80.0,
bool castShadows = true}) {
// TODO: implement addLight
throw UnimplementedError();
}
@override
Future clearBackgroundImage() {
// TODO: implement clearBackgroundImage
throw UnimplementedError();
}
@override
Future clearEntities() {
// TODO: implement clearEntities
throw UnimplementedError();
}
@override
Future clearLights() {
// TODO: implement clearLights
throw UnimplementedError();
}
@override
Future createGeometry(List<double> vertices, List<int> indices,
{String? materialPath,
PrimitiveType primitiveType = PrimitiveType.TRIANGLES}) {
// TODO: implement createGeometry
throw UnimplementedError();
}
@override
Future<ThermionEntity> createInstance(ThermionEntity entity) {
// TODO: implement createInstance
throw UnimplementedError();
}
@override
Future dispose() {
// TODO: implement dispose
throw UnimplementedError();
}
@override
Future<double> getAnimationDuration(
ThermionEntity entity, int animationIndex) {
// TODO: implement getAnimationDuration
throw UnimplementedError();
}
@override
Future<List<String>> getAnimationNames(ThermionEntity entity) {
// TODO: implement getAnimationNames
throw UnimplementedError();
}
@override
Future<ThermionEntity> getBone(ThermionEntity parent, int boneIndex,
{int skinIndex = 0}) {
// TODO: implement getBone
throw UnimplementedError();
}
@override
Future<List<String>> getBoneNames(ThermionEntity entity,
{int skinIndex = 0}) {
// TODO: implement getBoneNames
throw UnimplementedError();
}
@override
Future<double> getCameraCullingFar() {
// TODO: implement getCameraCullingFar
throw UnimplementedError();
}
@override
Future<double> getCameraCullingNear() {
// TODO: implement getCameraCullingNear
throw UnimplementedError();
}
@override
Future<Matrix4> getCameraCullingProjectionMatrix() {
// TODO: implement getCameraCullingProjectionMatrix
throw UnimplementedError();
}
@override
Future<Frustum> getCameraFrustum() {
// TODO: implement getCameraFrustum
throw UnimplementedError();
}
@override
Future<Matrix4> getCameraModelMatrix() {
// TODO: implement getCameraModelMatrix
throw UnimplementedError();
}
@override
Future<Vector3> getCameraPosition() {
// TODO: implement getCameraPosition
throw UnimplementedError();
}
@override
Future<Matrix4> getCameraProjectionMatrix() {
// TODO: implement getCameraProjectionMatrix
throw UnimplementedError();
}
@override
Future<Matrix3> getCameraRotation() {
// TODO: implement getCameraRotation
throw UnimplementedError();
}
@override
Future<Matrix4> getCameraViewMatrix() {
// TODO: implement getCameraViewMatrix
throw UnimplementedError();
}
@override
Future<List<ThermionEntity>> getChildEntities(
ThermionEntity parent, bool renderableOnly) {
// TODO: implement getChildEntities
throw UnimplementedError();
}
@override
Future<ThermionEntity> getChildEntity(
ThermionEntity parent, String childName) {
// TODO: implement getChildEntity
throw UnimplementedError();
}
@override
Future<List<String>> getChildEntityNames(ThermionEntity entity,
{bool renderableOnly = true}) {
// TODO: implement getChildEntityNames
throw UnimplementedError();
}
@override
Future<int> getInstanceCount(ThermionEntity entity) {
// TODO: implement getInstanceCount
throw UnimplementedError();
}
@override
Future<List<ThermionEntity>> getInstances(ThermionEntity entity) {
// TODO: implement getInstances
throw UnimplementedError();
}
@override
Future<Matrix4> getInverseBindMatrix(ThermionEntity parent, int boneIndex,
{int skinIndex = 0}) {
// TODO: implement getInverseBindMatrix
throw UnimplementedError();
}
@override
Future<Matrix4> getLocalTransform(ThermionEntity entity) {
// TODO: implement getLocalTransform
throw UnimplementedError();
}
@override
Future<ThermionEntity> getMainCamera() {
// TODO: implement getMainCamera
throw UnimplementedError();
}
@override
Future<List<String>> getMorphTargetNames(
ThermionEntity entity, ThermionEntity childEntity) {
// TODO: implement getMorphTargetNames
throw UnimplementedError();
}
@override
String? getNameForEntity(ThermionEntity entity) {
// TODO: implement getNameForEntity
throw UnimplementedError();
}
@override
Future<ThermionEntity?> getParent(ThermionEntity child) {
// TODO: implement getParent
throw UnimplementedError();
}
@override
Future<Matrix4> getWorldTransform(ThermionEntity entity) {
// TODO: implement getWorldTransform
throw UnimplementedError();
}
@override
// TODO: implement gizmo
AbstractGizmo? get gizmo => throw UnimplementedError();
@override
Future hide(ThermionEntity entity, String? meshName) {
// TODO: implement hide
throw UnimplementedError();
}
@override
// TODO: implement initialized
Future<bool> get initialized => throw UnimplementedError();
@override
Future<ThermionEntity> loadGlb(String path, {int numInstances = 1}) {
// TODO: implement loadGlb
throw UnimplementedError();
}
@override
Future<ThermionEntity> loadGltf(String path, String relativeResourcePath,
{bool force = false}) {
// TODO: implement loadGltf
throw UnimplementedError();
}
@override
Future loadIbl(String lightingPath, {double intensity = 30000}) {
// TODO: implement loadIbl
throw UnimplementedError();
}
@override
Future loadSkybox(String skyboxPath) {
// TODO: implement loadSkybox
throw UnimplementedError();
}
@override
Future moveCameraToAsset(ThermionEntity entity) {
// TODO: implement moveCameraToAsset
throw UnimplementedError();
}
@override
void onDispose(Future Function() callback) {
// TODO: implement onDispose
}
@override
Future panEnd() {
// TODO: implement panEnd
throw UnimplementedError();
}
@override
Future panStart(double x, double y) {
// TODO: implement panStart
throw UnimplementedError();
}
@override
Future panUpdate(double x, double y) {
// TODO: implement panUpdate
throw UnimplementedError();
}
@override
void pick(int x, int y) {
// TODO: implement pick
}
@override
// TODO: implement pickResult
Stream<FilamentPickResult> get pickResult => throw UnimplementedError();
@override
Future playAnimation(ThermionEntity entity, int index,
{bool loop = false,
bool reverse = false,
bool replaceActive = true,
double crossfade = 0.0}) {
// TODO: implement playAnimation
throw UnimplementedError();
}
@override
Future playAnimationByName(ThermionEntity entity, String name,
{bool loop = false,
bool reverse = false,
bool replaceActive = true,
double crossfade = 0.0}) {
// TODO: implement playAnimationByName
throw UnimplementedError();
}
@override
Future queuePositionUpdate(
ThermionEntity entity, double x, double y, double z,
{bool relative = false}) {
// TODO: implement queuePositionUpdate
throw UnimplementedError();
}
@override
Future queueRotationUpdate(
ThermionEntity entity, double rads, double x, double y, double z,
{bool relative = false}) {
// TODO: implement queueRotationUpdate
throw UnimplementedError();
}
@override
Future queueRotationUpdateQuat(ThermionEntity entity, Quaternion quat,
{bool relative = false}) {
// TODO: implement queueRotationUpdateQuat
throw UnimplementedError();
}
@override
Future removeAnimationComponent(ThermionEntity entity) {
// TODO: implement removeAnimationComponent
throw UnimplementedError();
}
@override
Future removeCollisionComponent(ThermionEntity entity) {
// TODO: implement removeCollisionComponent
throw UnimplementedError();
}
@override
Future removeEntity(ThermionEntity entity) {
// TODO: implement removeEntity
throw UnimplementedError();
}
@override
Future removeIbl() {
// TODO: implement removeIbl
throw UnimplementedError();
}
@override
Future removeLight(ThermionEntity light) {
// TODO: implement removeLight
throw UnimplementedError();
}
@override
Future removeSkybox() {
// TODO: implement removeSkybox
throw UnimplementedError();
}
@override
Future render() {
// TODO: implement render
throw UnimplementedError();
}
@override
// TODO: implement rendering
bool get rendering => throw UnimplementedError();
@override
Future resetBones(ThermionEntity entity) {
// TODO: implement resetBones
throw UnimplementedError();
}
@override
Future reveal(ThermionEntity entity, String? meshName) {
// TODO: implement reveal
throw UnimplementedError();
}
@override
Future rotateEnd() {
// TODO: implement rotateEnd
throw UnimplementedError();
}
@override
Future rotateIbl(Matrix3 rotation) {
// TODO: implement rotateIbl
throw UnimplementedError();
}
@override
Future rotateStart(double x, double y) {
// TODO: implement rotateStart
throw UnimplementedError();
}
@override
Future rotateUpdate(double x, double y) {
// TODO: implement rotateUpdate
throw UnimplementedError();
}
@override
// TODO: implement scene
Scene get scene => throw UnimplementedError();
@override
Future setAnimationFrame(
ThermionEntity entity, int index, int animationFrame) {
// TODO: implement setAnimationFrame
throw UnimplementedError();
}
@override
Future setAntiAliasing(bool msaa, bool fxaa, bool taa) {
// TODO: implement setAntiAliasing
throw UnimplementedError();
}
@override
Future setBackgroundColor(double r, double g, double b, double alpha) {
// TODO: implement setBackgroundColor
throw UnimplementedError();
}
@override
Future setBackgroundImage(String path, {bool fillHeight = false}) {
// TODO: implement setBackgroundImage
throw UnimplementedError();
}
@override
Future setBackgroundImagePosition(double x, double y, {bool clamp = false}) {
// TODO: implement setBackgroundImagePosition
throw UnimplementedError();
}
@override
Future setBloom(double bloom) {
// TODO: implement setBloom
throw UnimplementedError();
}
@override
Future setBoneTransform(
ThermionEntity entity, int boneIndex, Matrix4 transform,
{int skinIndex = 0}) {
// TODO: implement setBoneTransform
throw UnimplementedError();
}
@override
Future setCamera(ThermionEntity entity, String? name) {
// TODO: implement setCamera
throw UnimplementedError();
}
@override
Future setCameraCulling(double near, double far) {
// TODO: implement setCameraCulling
throw UnimplementedError();
}
@override
Future setCameraExposure(
double aperture, double shutterSpeed, double sensitivity) {
// TODO: implement setCameraExposure
throw UnimplementedError();
}
@override
Future setCameraFocalLength(double focalLength) {
// TODO: implement setCameraFocalLength
throw UnimplementedError();
}
@override
Future setCameraFocusDistance(double focusDistance) {
// TODO: implement setCameraFocusDistance
throw UnimplementedError();
}
@override
Future setCameraFov(double degrees, double width, double height) {
// TODO: implement setCameraFov
throw UnimplementedError();
}
@override
Future setCameraManipulatorOptions(
{ManipulatorMode mode = ManipulatorMode.ORBIT,
double orbitSpeedX = 0.01,
double orbitSpeedY = 0.01,
double zoomSpeed = 0.01}) {
// TODO: implement setCameraManipulatorOptions
throw UnimplementedError();
}
@override
Future setCameraModelMatrix(List<double> matrix) {
// TODO: implement setCameraModelMatrix
throw UnimplementedError();
}
@override
Future setCameraPosition(double x, double y, double z) {
// TODO: implement setCameraPosition
throw UnimplementedError();
}
@override
Future setCameraRotation(Quaternion quaternion) {
// TODO: implement setCameraRotation
throw UnimplementedError();
}
@override
Future setFrameRate(int framerate) {
// TODO: implement setFrameRate
throw UnimplementedError();
}
@override
Future setMainCamera() {
// TODO: implement setMainCamera
throw UnimplementedError();
}
@override
Future setMaterialColor(ThermionEntity entity, String meshName,
int materialIndex, double r, double g, double b, double a) {
// TODO: implement setMaterialColor
throw UnimplementedError();
}
@override
Future setMorphAnimationData(
ThermionEntity entity, MorphAnimationData animation,
{List<String>? targetMeshNames}) {
// TODO: implement setMorphAnimationData
throw UnimplementedError();
}
@override
Future setMorphTargetWeights(ThermionEntity entity, List<double> weights) {
// TODO: implement setMorphTargetWeights
throw UnimplementedError();
}
@override
Future setParent(ThermionEntity child, ThermionEntity parent) {
// TODO: implement setParent
throw UnimplementedError();
}
@override
Future setPosition(ThermionEntity entity, double x, double y, double z) {
// TODO: implement setPosition
throw UnimplementedError();
}
@override
Future setPostProcessing(bool enabled) {
// TODO: implement setPostProcessing
throw UnimplementedError();
}
@override
Future setPriority(ThermionEntity entityId, int priority) {
// TODO: implement setPriority
throw UnimplementedError();
}
@override
Future setRecording(bool recording) {
// TODO: implement setRecording
throw UnimplementedError();
}
@override
Future setRecordingOutputDirectory(String outputDirectory) {
// TODO: implement setRecordingOutputDirectory
throw UnimplementedError();
}
@override
Future setRendering(bool render) {
// TODO: implement setRendering
throw UnimplementedError();
}
@override
Future setRotation(
ThermionEntity entity, double rads, double x, double y, double z) {
// TODO: implement setRotation
throw UnimplementedError();
}
@override
Future setRotationQuat(ThermionEntity entity, Quaternion rotation) {
// TODO: implement setRotationQuat
throw UnimplementedError();
}
@override
Future setScale(ThermionEntity entity, double scale) {
// TODO: implement setScale
throw UnimplementedError();
}
@override
Future setToneMapping(ToneMapper mapper) {
// TODO: implement setToneMapping
throw UnimplementedError();
}
@override
Future setTransform(ThermionEntity entity, Matrix4 transform) {
// TODO: implement setTransform
throw UnimplementedError();
}
@override
Future setViewFrustumCulling(bool enabled) {
// TODO: implement setViewFrustumCulling
throw UnimplementedError();
}
@override
Future stopAnimation(ThermionEntity entity, int animationIndex) {
// TODO: implement stopAnimation
throw UnimplementedError();
}
@override
Future stopAnimationByName(ThermionEntity entity, String name) {
// TODO: implement stopAnimationByName
throw UnimplementedError();
}
@override
Future testCollisions(ThermionEntity entity) {
// TODO: implement testCollisions
throw UnimplementedError();
}
@override
Future transformToUnitCube(ThermionEntity entity) {
// TODO: implement transformToUnitCube
throw UnimplementedError();
}
@override
Future updateBoneMatrices(ThermionEntity entity) {
// TODO: implement updateBoneMatrices
throw UnimplementedError();
}
@override
Future zoomBegin() {
// TODO: implement zoomBegin
throw UnimplementedError();
}
@override
Future zoomEnd() {
// TODO: implement zoomEnd
throw UnimplementedError();
}
@override
Future zoomUpdate(double x, double y, double z) {
// TODO: implement zoomUpdate
throw UnimplementedError();
}
}

View File

@@ -13,8 +13,6 @@ extern "C"
{
extern EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context();
}
#include <pthread.h>
#endif
#include "ThermionDartFFIApi.h"
@@ -38,19 +36,26 @@ public:
explicit RenderLoop()
{
srand(time(NULL));
#ifdef __EMSCRIPTEN__
pthread_attr_t attr;
pthread_attr_init(&attr);
#ifdef __EMSCRIPTEN__
emscripten_pthread_attr_settransferredcanvases(&attr, "canvas");
#endif
pthread_create(&t, &attr, &RenderLoop::startHelper, this);
#else
t = new std::thread([this]() {
start();
});
#endif
}
~RenderLoop()
{
_stop = true;
#ifdef __EMSCRIPTEN__
pthread_join(t, NULL);
#else
t->join();
#endif
Log("Render loop killed");
}
@@ -209,13 +214,17 @@ public:
std::mutex _access;
void (*_renderCallback)(void *const) = nullptr;
void *_renderCallbackOwner = nullptr;
pthread_t t;
std::condition_variable _cond;
std::deque<std::function<void()>> _tasks;
FilamentViewer* _viewer = nullptr;
#ifdef __EMSCRIPTEN__
pthread_t t;
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE _context;
int _frameNum = 0;
#else
std::thread *t = nullptr;
#endif
};

View File

@@ -1,6 +1,6 @@
name: thermion_dart
description: 3D rendering toolkit for Dart.
version: 0.1.0+1
version: 0.1.1+2
homepage: https://docs.page/nmfisher/thermion
repository: https://github.com/nmfisher/thermion
@@ -15,6 +15,7 @@ dependencies:
native_toolchain_c: ^0.4.2
archive: ^3.6.1
web: ^0.5.1
logging: ^1.2.0
dev_dependencies:
ffigen: ^11.0.0

View File

@@ -1,9 +1,7 @@
import 'dart:ffi';
import 'dart:io';
import 'package:thermion_dart/thermion_dart/swift/swift_bindings.g.dart';
import 'package:thermion_dart/thermion_dart/thermion_viewer_ffi.dart';
import 'package:thermion_dart/thermion_dart/utils/dart_resources.dart';
import 'package:ffi/ffi.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:thermion_dart/thermion_dart/compatibility/compatibility.dart';
import 'package:test/test.dart';
import 'package:animation_tools_dart/animation_tools_dart.dart';

View File

@@ -1,3 +1,32 @@
## 0.1.1+7
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 0.1.1-dev.0+7
- **FIX**: add ResourceBuffer header directly to Windows build so I don't have to fiddle around getting the CMake path right.
## 0.1.1+6
- **DOCS**: update with links to playground.
## 0.1.1+5
- Update a dependency to the latest release.
## 0.1.1+4
- Update a dependency to the latest release.
## 0.1.1+3
- Update a dependency to the latest release.
## 0.1.1+2
- **FIX**: update Flutter example project to use new API.
- **FIX**: add logging dependency to thermion_flutter.
## 0.1.1+1
- **REFACTOR**: export ThermionViewerWasm for web and hide FFI/WASM version.

View File

@@ -3,7 +3,8 @@
<p align="center">
<a href="https://docs.page/nmfisher/flutter_filament/quickstart">Quickstart (Flutter)</a> •
<a href="https://docs.page/nmfisher/flutter_filament">Documentation</a> •
<a href="https://github.com/nmfisher/thermion/docs/examples/">Showcase</a> •
<a href="https://github.com/nmfisher/thermion/docs/examples/">Showcase</a> •
<a href="https://dartpad.thermion.dev/">Playground</a> •
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
</p>

View File

@@ -3,4 +3,5 @@ library thermion_flutter;
export 'thermion/thermion_flutter_plugin.dart';
export 'thermion/widgets/thermion_widget.dart';
export 'thermion/widgets/camera/gestures/thermion_gesture_detector.dart';
export 'package:thermion_dart/thermion_dart.dart';

View File

@@ -1,6 +1,6 @@
name: thermion_flutter
description: Flutter plugin for 3D rendering with the Thermion toolkit.
version: 0.1.1+1
version: 0.1.1+7
homepage: https://docs.page/nmfisher/thermion
repository: https://github.com/nmfisher/thermion
@@ -17,10 +17,11 @@ dependencies:
plugin_platform_interface: ^2.0.0
ffi: ^2.1.2
animation_tools_dart: ^0.0.4
thermion_dart: ^0.1.0+1
thermion_flutter_platform_interface: ^0.1.0+1
thermion_flutter_ffi: ^0.1.0+1
thermion_flutter_web: ^0.0.1+1
thermion_dart: ^0.1.1+2
thermion_flutter_platform_interface: ^0.1.0+6
thermion_flutter_ffi: ^0.1.0+6
thermion_flutter_web: ^0.0.1+6
logging: ^1.2.0
dev_dependencies:
flutter_test:

View File

@@ -12,7 +12,7 @@
#pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "comctl32.lib")
namespace thermion_filament {
namespace thermion_flutter {
static constexpr auto kClassName = L"FLUTTER_FILAMENT_WINDOW";
static constexpr auto kWindowName = L"thermion_flutter_window";
@@ -354,4 +354,4 @@ void BackingWindow::Resize(int width, int height, int left, int top) {
}
HWND BackingWindow::GetHandle() { return _windowHandle; }
} // namespace thermion_filament
} // namespace thermion_flutter

View File

@@ -5,7 +5,7 @@
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
namespace thermion_filament {
namespace thermion_flutter {
class BackingWindow {
public:

View File

@@ -7,7 +7,7 @@
#pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "comctl32.lib")
namespace thermion_filament {
namespace thermion_flutter {
FlutterEGLContext::FlutterEGLContext(
flutter::PluginRegistrarWindows* pluginRegistrar,

View File

@@ -12,7 +12,7 @@
#include "backend/platforms/PlatformEGL.h"
#include "flutter_render_context.h"
namespace thermion_filament {
namespace thermion_flutter {
class FlutterEGLContext : public FlutterRenderContext {
public:

View File

@@ -7,7 +7,7 @@
#include <thread>
namespace thermion_filament {
namespace thermion_flutter {
static void logEglError(const char *name) noexcept {
const char *err;
@@ -240,4 +240,4 @@ FlutterAngleTexture::FlutterAngleTexture(
result->Success(resultList);
}
} // namespace thermion_filament
} // namespace thermion_flutter

View File

@@ -26,7 +26,7 @@
typedef uint32_t GLuint;
namespace thermion_filament {
namespace thermion_flutter {
class FlutterAngleTexture : public FlutterTextureBuffer {
public:

View File

@@ -8,7 +8,7 @@
#include "flutter_texture_buffer.h"
namespace thermion_filament {
namespace thermion_flutter {
class FlutterRenderContext {
public:

View File

@@ -7,7 +7,7 @@
#include <flutter/texture_registrar.h>
namespace thermion_filament {
namespace thermion_flutter {
class FlutterTextureBuffer {
public:

View File

@@ -0,0 +1,44 @@
#ifndef RESOURCE_BUFFER_H
#define RESOURCE_BUFFER_H
#include <stdint.h>
#include <stdlib.h>
//
// A ResourceBuffer is a unified interface for working with
// binary assets across various platforms.
// This is simply:
// 1) a pointer to some data
// 2) the length of the data
// 3) an ID that can be passed back to the native platform to release the underlying asset when needed.
//
typedef struct ResourceBuffer
{
const void *const data;
const int32_t size;
const int32_t id;
#if defined(__cplusplus)
ResourceBuffer(void *const data, int32_t size, int32_t id) : data(data), size(size), id(id) {}
#endif
} ResourceBuffer;
typedef void (*LoadFilamentResourceIntoOutPointer)(const char *uri, ResourceBuffer *out);
typedef ResourceBuffer (*LoadFilamentResource)(const char *uri);
typedef ResourceBuffer (*LoadFilamentResourceFromOwner)(const char *const, void *const owner);
typedef void (*FreeFilamentResource)(ResourceBuffer);
typedef void (*FreeFilamentResourceFromOwner)(ResourceBuffer, void *const owner);
typedef struct ResourceLoaderWrapper
{
LoadFilamentResource loadResource;
FreeFilamentResource freeResource;
LoadFilamentResourceFromOwner loadFromOwner;
FreeFilamentResourceFromOwner freeFromOwner;
void *owner;
LoadFilamentResourceIntoOutPointer loadToOut;
} ResourceLoaderWrapper;
void *make_resource_loader(LoadFilamentResourceFromOwner loadFn, FreeFilamentResourceFromOwner freeFn, void *const owner);
#endif

View File

@@ -7,7 +7,7 @@
#include <thread>
namespace thermion_filament {
namespace thermion_flutter {
void _release_callback(void *releaseContext) {
// ((OpenGLTextureBuffer*)releaseContext)->unlock();
@@ -141,4 +141,4 @@ OpenGLTextureBuffer::~OpenGLTextureBuffer() {
wglMakeCurrent(NULL, NULL);
}
} // namespace thermion_filament
} // namespace thermion_flutter

View File

@@ -20,7 +20,7 @@
typedef uint32_t GLuint;
namespace thermion_filament {
namespace thermion_flutter {
class OpenGLTextureBuffer : public FlutterTextureBuffer {
public:

View File

@@ -10,7 +10,7 @@
#include "thermion_flutter_plugin.h"
namespace thermion_filament {
namespace thermion_flutter {
namespace test {
namespace {
@@ -40,4 +40,4 @@ TEST(ThermionFlutterPlugin, GetPlatformVersion) {
}
} // namespace test
} // namespace thermion_filament
} // namespace thermion_flutter

View File

@@ -35,7 +35,7 @@
#include "wgl_context.h"
#endif
namespace thermion_filament {
namespace thermion_flutter {
using namespace std::chrono_literals;
@@ -61,7 +61,6 @@ ThermionFlutterPlugin::ThermionFlutterPlugin(
// attach the method call handler for incoming messages
_channel->SetMethodCallHandler([=](const auto &call, auto result) {
std::cout << call.method_name() << std::endl;
this->HandleMethodCall(call, std::move(result));
});
}
@@ -275,4 +274,4 @@ void ThermionFlutterPlugin::HandleMethodCall(
}
}
} // namespace thermion_filament
} // namespace thermion_flutter

View File

@@ -14,7 +14,7 @@
#include "GL/GL.h"
#include "GL/GLu.h"
#include "ResourceBuffer.hpp"
#include "ResourceBuffer.h"
#if USE_ANGLE
#include "egl_context.h"
@@ -22,7 +22,7 @@
#include "wgl_context.h"
#endif
namespace thermion_filament {
namespace thermion_flutter {
class ThermionFlutterPlugin : public flutter::Plugin {
public:
@@ -66,6 +66,6 @@ public:
#endif
};
} // namespace thermion_filament
} // namespace thermion_flutter
#endif // FLUTTER_PLUGIN_FLUTTER_FILAMENT_PLUGIN_H_

View File

@@ -6,7 +6,7 @@
#include "flutter_texture_buffer.h"
namespace thermion_filament {
namespace thermion_flutter {
WGLContext::WGLContext(flutter::PluginRegistrarWindows *pluginRegistrar,
flutter::TextureRegistrar *textureRegistrar)
@@ -143,4 +143,4 @@ void WGLContext::CreateRenderingSurface(
void *WGLContext::GetSharedContext() { return (void *)_context; }
} // namespace thermion_filament
} // namespace thermion_flutter

View File

@@ -7,7 +7,7 @@
#if WGL_USE_BACKING_WINDOW
#include "backing_window.h"
#endif
namespace thermion_filament {
namespace thermion_flutter {
class WGLContext : public FlutterRenderContext {
public:

View File

@@ -1,3 +1,27 @@
## 0.1.0+6
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 0.1.0-dev.0+6
- Update a dependency to the latest release.
## 0.1.0+5
- Update a dependency to the latest release.
## 0.1.0+4
- Update a dependency to the latest release.
## 0.1.0+3
- Update a dependency to the latest release.
## 0.1.0+2
- **REFACTOR**: rearrange some stubs/imports for easier web WASM deployment.
## 0.1.0+1
- Update a dependency to the latest release.

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/services.dart';
import 'dart:ffi';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:thermion_dart/thermion_dart/thermion_viewer_ffi.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_platform_interface.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';

View File

@@ -1,7 +1,7 @@
name: thermion_flutter_ffi
description: An FFI interface for the thermion_flutter plugin (all platforms except web).
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
version: 0.1.0+1
version: 0.1.0+6
environment:
sdk: ">=3.3.0 <4.0.0"
@@ -22,8 +22,8 @@ dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.0
thermion_flutter_platform_interface: ^0.1.0+1
thermion_dart: ^0.1.0+1
thermion_flutter_platform_interface: ^0.1.0+6
thermion_dart: ^0.1.1+2
dev_dependencies:
flutter_test:

View File

@@ -1,3 +1,27 @@
## 0.1.0+6
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 0.1.0-dev.0+6
- Update a dependency to the latest release.
## 0.1.0+5
- Update a dependency to the latest release.
## 0.1.0+4
- Update a dependency to the latest release.
## 0.1.0+3
- Update a dependency to the latest release.
## 0.1.0+2
- Update a dependency to the latest release.
## 0.1.0+1
- Update a dependency to the latest release.

View File

@@ -1,7 +1,7 @@
name: thermion_flutter_platform_interface
description: A common platform interface for the thermion_flutter plugin.
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
version: 0.1.0+1
version: 0.1.0+6
environment:
sdk: ">=3.3.0 <4.0.0"
@@ -11,7 +11,7 @@ dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.0
thermion_dart: ^0.1.0+1
thermion_dart: ^0.1.1+2
dev_dependencies:
flutter_test:

View File

@@ -1,3 +1,27 @@
## 0.0.1+6
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 0.0.1-dev.0+6
- Update a dependency to the latest release.
## 0.0.1+5
- Update a dependency to the latest release.
## 0.0.1+4
- Update a dependency to the latest release.
## 0.0.1+3
- Update a dependency to the latest release.
## 0.0.1+2
- Update a dependency to the latest release.
## 0.0.1+1
- **REFACTOR**: export ThermionViewerWasm for web and hide FFI/WASM version.

View File

@@ -1,7 +1,7 @@
name: thermion_flutter_web
description: A web platform interface for the thermion_flutter plugin.
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
version: 0.0.1+1
version: 0.0.1+6
environment:
sdk: ">=3.3.0 <4.0.0"
@@ -20,8 +20,8 @@ dependencies:
sdk: flutter
plugin_platform_interface: ^2.1.0
web: ^0.5.1
thermion_dart: ^0.1.0+1
thermion_flutter_platform_interface: ^0.1.0+1
thermion_dart: ^0.1.1+2
thermion_flutter_platform_interface: ^0.1.0+6
flutter_web_plugins:
sdk: flutter