Compare commits
94 Commits
thermion_f
...
thermion_d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb517c907d | ||
|
|
a6f5e59cbb | ||
|
|
9420143a36 | ||
|
|
eb8835b63a | ||
|
|
f9468db266 | ||
|
|
1135ba054c | ||
|
|
8f7509a23f | ||
|
|
cba9ee98ad | ||
|
|
0ec0fef8f3 | ||
|
|
a348562f56 | ||
|
|
392a606bbc | ||
|
|
440bed4485 | ||
|
|
a321966e5b | ||
|
|
f180c1018f | ||
|
|
f267aa6dc6 | ||
|
|
1c74e83c2c | ||
|
|
099a895eb6 | ||
|
|
3b810f84da | ||
|
|
10f2c7d36b | ||
|
|
5b849638de | ||
|
|
857fd6f782 | ||
|
|
29edec63ab | ||
|
|
c6afc4756a | ||
|
|
365657cf88 | ||
|
|
5441dedcf4 | ||
|
|
254b6d8af2 | ||
|
|
1459aea5cf | ||
|
|
80d8525671 | ||
|
|
389a165ed3 | ||
|
|
d8f309d21b | ||
|
|
ee983ddfaa | ||
|
|
c1cdd37e9d | ||
|
|
646f05933d | ||
|
|
3f854a7f27 | ||
|
|
740dbea8bd | ||
|
|
95a44936ac | ||
|
|
9deafc7371 | ||
|
|
c1af7e374d | ||
|
|
cd71db72be | ||
|
|
a9d90f966b | ||
|
|
1a323ca551 | ||
|
|
2d85e191bc | ||
|
|
1b971a859c | ||
|
|
78b697d1c2 | ||
|
|
9da2ce6672 | ||
|
|
39fabd501d | ||
|
|
3f1867dd6f | ||
|
|
68d29041b0 | ||
|
|
b300e86962 | ||
|
|
562ecf2ee5 | ||
|
|
d294938a2c | ||
|
|
027cf23069 | ||
|
|
c4598637bb | ||
|
|
8a94b6a334 | ||
|
|
c80c163212 | ||
|
|
921a994eb6 | ||
|
|
65e60da288 | ||
|
|
661185083e | ||
|
|
a2a26555e2 | ||
|
|
7f11250b79 | ||
|
|
a6d2f2ecf9 | ||
|
|
399d447eec | ||
|
|
fb6204e47c | ||
|
|
566856c8fb | ||
|
|
d29dd207b6 | ||
|
|
e20489900d | ||
|
|
567a268ded | ||
|
|
6a57d242f9 | ||
|
|
41e0851d70 | ||
|
|
95b378348c | ||
|
|
1309bf7c6e | ||
|
|
2531b507b0 | ||
|
|
16dc0419e2 | ||
|
|
4e7ec6bfb4 | ||
|
|
035ad48fe4 | ||
|
|
ff7c582157 | ||
|
|
0876a91e17 | ||
|
|
a2d3c1d73e | ||
|
|
1a721deee6 | ||
|
|
4355d9c83f | ||
|
|
239891c400 | ||
|
|
ac10aa0a1e | ||
|
|
7ecf414a47 | ||
|
|
87c96d06a4 | ||
|
|
26a8d9c6b5 | ||
|
|
947a77f619 | ||
|
|
c850513b7f | ||
|
|
c47d827139 | ||
|
|
a2684ae47d | ||
|
|
2b1339b560 | ||
|
|
59aec2bcc9 | ||
|
|
61d1581b96 | ||
|
|
8e47332ce8 | ||
|
|
ffe8bee98b |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -36,7 +36,7 @@ thermion_dart/native/lib/macos/debug/libmatlang.a filter=lfs diff=lfs merge=lfs
|
||||
thermion_dart/native/lib/macos/debug/libibl.a filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/debug/libmikktspace.a filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/libmatdbg_combined.a filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/swift/ThermionDartTexture.h filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/swift/ThermionTexture.h filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/debug/libfilamat_combined.a filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/debug/libfilament.a filter=lfs diff=lfs merge=lfs -text
|
||||
thermion_dart/native/lib/macos/libibl.a filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
475
CHANGELOG.md
475
CHANGELOG.md
@@ -3,7 +3,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## 2024-09-25
|
||||
## 2024-10-14
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -11,53 +11,33 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_flutter` - `v0.2.0-dev.6.0`](#thermion_flutter---v020-dev60)
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- There are no other changes in this release.
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_flutter` - `v0.2.0-dev.6.0`
|
||||
|
||||
- **BREAKING** **CHORE**: remove superseded HardwareKeyboard* classes.
|
||||
|
||||
|
||||
## 2024-09-25
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.0-dev.5.0`](#thermion_dart---v020-dev50)
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_flutter_web` - `v0.1.0-dev.5.0`](#thermion_flutter_web---v010-dev50)
|
||||
- [`thermion_flutter` - `v0.2.0-dev.5.0`](#thermion_flutter---v020-dev50)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.0-dev.5.0`](#thermion_flutter_platform_interface---v020-dev50)
|
||||
- [`thermion_flutter_ffi` - `v0.2.0-dev.5.0`](#thermion_flutter_ffi---v020-dev50)
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.8`](#thermion_dart---v021-dev008)
|
||||
- [`thermion_flutter_web` - `v0.1.0+9`](#thermion_flutter_web---v0109)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.7`](#thermion_flutter---v021-dev7)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.7`](#thermion_flutter_platform_interface---v021-dev7)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.7`](#thermion_flutter_ffi---v021-dev7)
|
||||
|
||||
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.1.0-dev.5.0`
|
||||
- `thermion_flutter` - `v0.2.0-dev.5.0`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.0-dev.5.0`
|
||||
- `thermion_flutter_ffi` - `v0.2.0-dev.5.0`
|
||||
- `thermion_flutter_web` - `v0.1.0+9`
|
||||
- `thermion_flutter` - `v0.2.1-dev.7`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.7`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.7`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.0-dev.5.0`
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.8`
|
||||
|
||||
- **BREAKING** **CHORE**: remove EntityTransformController (requires replacement).
|
||||
- **FIX**: move ThermionWin32.h to include.
|
||||
|
||||
|
||||
## 2024-09-25
|
||||
## 2024-10-14
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -65,36 +45,33 @@ Packages with dependency updates only:
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.0-dev.4.0`](#thermion_dart---v020-dev40)
|
||||
- [`thermion_flutter_web` - `v0.1.0-dev.4.0`](#thermion_flutter_web---v010-dev40)
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_flutter` - `v0.2.0-dev.4.0`](#thermion_flutter---v020-dev40)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.0-dev.4.0`](#thermion_flutter_platform_interface---v020-dev40)
|
||||
- [`thermion_flutter_ffi` - `v0.2.0-dev.4.0`](#thermion_flutter_ffi---v020-dev40)
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.7`](#thermion_dart---v021-dev007)
|
||||
- [`thermion_flutter_web` - `v0.1.0+8`](#thermion_flutter_web---v0108)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.6`](#thermion_flutter---v021-dev6)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.6`](#thermion_flutter_platform_interface---v021-dev6)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.6`](#thermion_flutter_ffi---v021-dev6)
|
||||
|
||||
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` - `v0.2.0-dev.4.0`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.0-dev.4.0`
|
||||
- `thermion_flutter_ffi` - `v0.2.0-dev.4.0`
|
||||
- `thermion_flutter_web` - `v0.1.0+8`
|
||||
- `thermion_flutter` - `v0.2.1-dev.6`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.6`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.6`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.0-dev.4.0`
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.7`
|
||||
|
||||
- **BREAKING** **FIX**: (web/wasm) free pick callbacks on dispose.
|
||||
- **BREAKING** **CHORE**: restructure viewer folders as libraries to only export the public interface.
|
||||
|
||||
#### `thermion_flutter_web` - `v0.1.0-dev.4.0`
|
||||
|
||||
- **BREAKING** **CHORE**: restructure viewer folders as libraries to only export the public interface.
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.7`.
|
||||
|
||||
|
||||
## 2024-09-25
|
||||
## 2024-10-10
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -102,21 +79,33 @@ Packages with dependency updates only:
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_flutter` - `v0.2.0-dev.3.0`](#thermion_flutter---v020-dev30)
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- There are no other changes in this release.
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.6`](#thermion_dart---v021-dev006)
|
||||
- [`thermion_flutter_web` - `v0.1.0+7`](#thermion_flutter_web---v0107)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.5`](#thermion_flutter_platform_interface---v021-dev5)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.5`](#thermion_flutter---v021-dev5)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.5`](#thermion_flutter_ffi---v021-dev5)
|
||||
|
||||
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.1.0+7`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.5`
|
||||
- `thermion_flutter` - `v0.2.1-dev.5`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.5`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_flutter` - `v0.2.0-dev.3.0`
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.6`
|
||||
|
||||
- **BREAKING** **FIX**: remove EntityControllerMouseWidget (replace with GestureHandler).
|
||||
- **BREAKING** **CHORE**: (flutter) cleanup for pub.dev publishing.
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.6`.
|
||||
|
||||
|
||||
## 2024-09-25
|
||||
## 2024-10-10
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -124,20 +113,33 @@ Packages with other changes:
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_flutter` - `v0.2.0-dev.2.0`](#thermion_flutter---v020-dev20)
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- There are no other changes in this release.
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.5`](#thermion_dart---v021-dev005)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.4`](#thermion_flutter_platform_interface---v021-dev4)
|
||||
- [`thermion_flutter_web` - `v0.1.0+6`](#thermion_flutter_web---v0106)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.4`](#thermion_flutter---v021-dev4)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.4`](#thermion_flutter_ffi---v021-dev4)
|
||||
|
||||
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.2.1-dev.4`
|
||||
- `thermion_flutter_web` - `v0.1.0+6`
|
||||
- `thermion_flutter` - `v0.2.1-dev.4`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.4`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_flutter` - `v0.2.0-dev.2.0`
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.5`
|
||||
|
||||
- **BREAKING** **CHORE**: remove EntityListWidget - will replace with new Scene.
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.5`.
|
||||
|
||||
|
||||
## 2024-09-25
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -145,40 +147,295 @@ Packages with other changes:
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.0-dev.1.0`](#thermion_dart---v020-dev10)
|
||||
- [`thermion_flutter` - `v0.2.0-dev.1.0`](#thermion_flutter---v020-dev10)
|
||||
- [`thermion_flutter_ffi` - `v0.2.0-dev.1.0`](#thermion_flutter_ffi---v020-dev10)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.0-dev.1.0`](#thermion_flutter_platform_interface---v020-dev10)
|
||||
- [`thermion_flutter_web` - `v0.1.0-dev.1.0`](#thermion_flutter_web---v010-dev10)
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- There are no other changes in this release.
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.4`](#thermion_dart---v021-dev004)
|
||||
- [`thermion_flutter_web` - `v0.1.0+5`](#thermion_flutter_web---v0105)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.3`](#thermion_flutter---v021-dev3)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.3`](#thermion_flutter_platform_interface---v021-dev3)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.3`](#thermion_flutter_ffi---v021-dev3)
|
||||
|
||||
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.1.0+5`
|
||||
- `thermion_flutter` - `v0.2.1-dev.3`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.3`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.3`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.0-dev.1.0`
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.4`
|
||||
|
||||
- **REFACTOR**: native types.
|
||||
- **REFACTOR**: native types.
|
||||
- **REFACTOR**: move native types to own header, add methods for create/destroy material instance, add priority/layer to load_glb_from_buffer.
|
||||
- **REFACTOR**: Dart types.
|
||||
- **FIX**: (web) add emscripten guards for flushAndWait call when swapchain destroyed.
|
||||
- **FIX**: ignore pick results directly on axis.
|
||||
- **FIX**: properly destroy entities/material/etc in Gizmo on destruction, remove custom scene creation logic.
|
||||
- **FIX**: add check for nan NDC coordinates for viewport translation.
|
||||
- **FIX**: (wasm) use correct coords for pick, free memory correctly, keep pixelratio copy.
|
||||
- **FIX**: add more nan checks for gizmo manipulation.
|
||||
- **FIX**: emscripten export visibility for add_light.
|
||||
- **FIX**: add Fence to capture() and set stencil buffer by default.
|
||||
- **FEAT**: add removeStencilHighlight, queuePositionUpdateFromViewportCoords to ThermionViewer.
|
||||
- **FEAT**: add removeStencilHighlight, accept color param for setStencilHighlight, queuePositionUpdateFromViewportCoords to ThermionDartApi.
|
||||
- **FEAT**: add flag for keepData for gltf instancing, add highlightScene, add stencilHighlight method.
|
||||
- **FEAT**: grid uses own material.
|
||||
- **FEAT**: parent the cloned entity instance when setting stencil highlight.
|
||||
- **FEAT**: add grid material.
|
||||
- **FEAT**: expose setLightDirection and setLightPosition.
|
||||
- **FEAT**: move HighlightOverlay to nested class, move createGeometry to SceneManager, add queueRelativePositionUpdateFromViewportVector.
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.3`](#thermion_dart---v021-dev003)
|
||||
- [`thermion_flutter_web` - `v0.1.0+4`](#thermion_flutter_web---v0104)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.2`](#thermion_flutter---v021-dev2)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.2`](#thermion_flutter_platform_interface---v021-dev2)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.2`](#thermion_flutter_ffi---v021-dev2)
|
||||
|
||||
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.1.0+4`
|
||||
- `thermion_flutter` - `v0.2.1-dev.2`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.2`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.2`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.3`
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.3`.
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.2`](#thermion_dart---v021-dev002)
|
||||
- [`thermion_flutter_web` - `v0.1.0+3`](#thermion_flutter_web---v0103)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.1`](#thermion_flutter_ffi---v021-dev1)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.1`](#thermion_flutter---v021-dev1)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.1`](#thermion_flutter_platform_interface---v021-dev1)
|
||||
|
||||
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.1.0+3`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.1`
|
||||
- `thermion_flutter` - `v0.2.1-dev.1`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.1`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.2`
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.1`](#thermion_dart---v021-dev001)
|
||||
- [`thermion_flutter_web` - `v0.1.0+2`](#thermion_flutter_web---v0102)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.0`](#thermion_flutter---v021-dev0)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.0`](#thermion_flutter_platform_interface---v021-dev0)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.0`](#thermion_flutter_ffi---v021-dev0)
|
||||
|
||||
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.1.0+2`
|
||||
- `thermion_flutter` - `v0.2.1-dev.0`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.1-dev.0`
|
||||
- `thermion_flutter_ffi` - `v0.2.1-dev.0`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.1`
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.1-dev.0.0.0`](#thermion_dart---v021-dev000)
|
||||
- [`thermion_flutter` - `v0.2.1-dev.0.0.0`](#thermion_flutter---v021-dev000)
|
||||
- [`thermion_flutter_ffi` - `v0.2.1-dev.0.0.0`](#thermion_flutter_ffi---v021-dev000)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.0.0.0`](#thermion_flutter_platform_interface---v021-dev000)
|
||||
- [`thermion_flutter_web` - `v0.1.0+1`](#thermion_flutter_web---v0101)
|
||||
|
||||
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.1.0+1`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.1-dev.0.0.0`
|
||||
|
||||
- y
|
||||
|
||||
#### `thermion_flutter` - `v0.2.1-dev.0.0.0`
|
||||
|
||||
- y
|
||||
|
||||
#### `thermion_flutter_ffi` - `v0.2.1-dev.0.0.0`
|
||||
|
||||
- y
|
||||
|
||||
#### `thermion_flutter_platform_interface` - `v0.2.1-dev.0.0.0`
|
||||
|
||||
- y
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.0`](#thermion_dart---v020)
|
||||
- [`thermion_flutter` - `v0.2.0`](#thermion_flutter---v020)
|
||||
- [`thermion_flutter_ffi` - `v0.2.0`](#thermion_flutter_ffi---v020)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.0`](#thermion_flutter_platform_interface---v020)
|
||||
- [`thermion_flutter_web` - `v0.1.0`](#thermion_flutter_web---v010)
|
||||
|
||||
Packages graduated to a stable release (see pre-releases prior to the stable version for changelog entries):
|
||||
|
||||
- `thermion_dart` - `v0.2.0`
|
||||
- `thermion_flutter` - `v0.2.0`
|
||||
- `thermion_flutter_ffi` - `v0.2.0`
|
||||
- `thermion_flutter_platform_interface` - `v0.2.0`
|
||||
- `thermion_flutter_web` - `v0.1.0`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.0`
|
||||
|
||||
#### `thermion_flutter` - `v0.2.0`
|
||||
|
||||
#### `thermion_flutter_ffi` - `v0.2.0`
|
||||
|
||||
#### `thermion_flutter_platform_interface` - `v0.2.0`
|
||||
|
||||
#### `thermion_flutter_web` - `v0.1.0`
|
||||
|
||||
|
||||
## 2024-10-02
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- [`thermion_dart` - `v0.2.0-dev.8.0.0`](#thermion_dart---v020-dev800)
|
||||
- [`thermion_flutter_ffi` - `v0.2.0-dev.8.0.0`](#thermion_flutter_ffi---v020-dev800)
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_flutter` - `v0.2.0-dev.8.0.0`](#thermion_flutter---v020-dev800)
|
||||
- [`thermion_flutter_platform_interface` - `v0.2.0-dev.8.0.0`](#thermion_flutter_platform_interface---v020-dev800)
|
||||
- [`thermion_flutter_web` - `v0.1.0-dev.8.0.0`](#thermion_flutter_web---v010-dev800)
|
||||
|
||||
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.1.0-dev.8.0.0`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.2.0-dev.8.0.0`
|
||||
|
||||
- **REFACTOR**: continual refactor to support multiple render targets.
|
||||
- **FEAT**: camera and resizing improvements.
|
||||
- **FEAT**: support multiple ThermionWidget on Android.
|
||||
- **FEAT**: use imported texture on iOS.
|
||||
- **FEAT**: working implementation of multiple widgets on macos.
|
||||
- **FEAT**: more work on multiple views/swapchains.
|
||||
- **FEAT**: add setParameterFloat2 method.
|
||||
- **FEAT**: add setParameterFloat2 method.
|
||||
- **FEAT**: add uvScale to unlit material.
|
||||
- **FEAT**: add ThirdPersonCameraDelegate.
|
||||
- **FEAT**: set camera model matrix directly.
|
||||
- **FEAT**: expose more camera methods.
|
||||
- **BREAKING** **REFACTOR**: refactor to support multiple Views/Render Targets.
|
||||
- **BREAKING** **REFACTOR**: remove RenderThread methods no longer needed.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FEAT**: big refactor to support multiple swapchains.
|
||||
- **BREAKING** **FEAT**: set baseColorIndex to -1 by default in unlit materialss.
|
||||
|
||||
#### `thermion_flutter_ffi` - `v0.2.0-dev.8.0.0`
|
||||
|
||||
- **REFACTOR**: continual refactor to support multiple render targets.
|
||||
- **FEAT**: support multiple ThermionWidget on Android.
|
||||
- **FEAT**: use imported texture on iOS.
|
||||
- **FEAT**: working implementation of multiple widgets on macos.
|
||||
- **BREAKING** **REFACTOR**: refactor to support multiple Views/Render Targets.
|
||||
- **BREAKING** **FEAT**: big refactor to support multiple swapchains.
|
||||
|
||||
#### `thermion_flutter` - `v0.2.0-dev.8.0.0`
|
||||
|
||||
- **REFACTOR**: continual refactor to support multiple render targets.
|
||||
- **FEAT**: camera and resizing improvements.
|
||||
- **FEAT**: support multiple ThermionWidget on Android.
|
||||
- **FEAT**: use imported texture on iOS.
|
||||
- **FEAT**: working implementation of multiple widgets on macos.
|
||||
- **FEAT**: add rendering check to ThermionWidget ticker.
|
||||
|
||||
#### `thermion_flutter_platform_interface` - `v0.2.0-dev.8.0.0`
|
||||
|
||||
- **REFACTOR**: continual refactor to support multiple render targets.
|
||||
- **FEAT**: support multiple ThermionWidget on Android.
|
||||
- **FEAT**: working implementation of multiple widgets on macos.
|
||||
|
||||
# Change Log
|
||||
|
||||
v0.2.0
|
||||
|
||||
- **BREAKING** Dart SDK 3.6.0 required
|
||||
- **BREAKING** Libraries have been restructured so you should only need to import `package:thermion_dart/thermion_dart.dart`, `package:thermion_flutter/thermion_flutter.dart`
|
||||
- **BREAKING** The former GestureDetector widgets and EntityControllerMouseWidget/EntityTransformController have been removed and replaced with ThermionListenerWidget. that accepts an InputHandler.
|
||||
- **BREAKING** The former debugging widgets and Scene class have been removed.
|
||||
- **REFACTOR** The creation of the main camera has been refactored; the default projection & near/far planes should not have changed, but pay close attention.
|
||||
- **REFACTOR**: add methods for create/destroy material instance, add priority/layer to load_glb_from_buffer.
|
||||
- **FEAT**: Translation gizmo, stencil highlight & overlays.
|
||||
- **FEAT**: new setLightDirection and setLightPosition.
|
||||
- **FEAT**: move HighlightOverlay to nested class, move createGeometry to SceneManager, add queueRelativePositionUpdateFromViewportVector.
|
||||
- **FEAT**: move createGeometry to SceneManager, add queueRelativePositionUpdateFromViewportVector and removeStencilHighlight.
|
||||
- **FEAT**: add setGizmoVisibility/pickGizmo methods to ThermionViewer.
|
||||
- **FEAT**: remove gizmo view references, exclude gizmo entities from picking, add createIbl.
|
||||
@@ -206,9 +463,6 @@ Packages with other changes:
|
||||
- **FEAT**: createIbl.
|
||||
- **BREAKING** **FEAT**: (web) (flutter) create canvas when createViewer is called (no longer need to manually add canvas element to web HTML).
|
||||
- **BREAKING** **FEAT**: update web/http dependencies.
|
||||
|
||||
#### `thermion_flutter` - `v0.2.0-dev.1.0`
|
||||
|
||||
- **FIX**: (flutter) pass ThermionFlutterOptions to ThermionWidget, use dpr for resizeTexture, delete unnecessary TransparencyPainter class.
|
||||
- **FIX**: (flutter/web) use window.devicePixelRatio for viewport.
|
||||
- **FIX**: (flutter) desktop gesture detector changes for new Gizmo methods.
|
||||
@@ -222,20 +476,11 @@ Packages with other changes:
|
||||
- **BREAKING** **FEAT**: (web) (flutter) create canvas when createViewer is called (no longer need to manually add canvas element to web HTML).
|
||||
- **BREAKING** **FEAT**: resize canvas on web.
|
||||
- **BREAKING** **CHORE**: rename controller to viewer in gesture detector widgets.
|
||||
|
||||
#### `thermion_flutter_ffi` - `v0.2.0-dev.1.0`
|
||||
|
||||
- **FEAT**: (flutter) move DPR calculation to resizeTexture and add createViewerWithOptions method to ThermionFlutterFFI.
|
||||
- **BREAKING** **FIX**: (flutter) pass pixelRatio to createTexture.
|
||||
|
||||
#### `thermion_flutter_platform_interface` - `v0.2.0-dev.1.0`
|
||||
|
||||
- **FEAT**: add createViewerWithOptions to ThermionFlutterPlugin and mark createViewer as deprecated.
|
||||
- **FEAT**: add ThermionFlutterOptions classes, rename interface parameter for offsetTop and ensure pixelRatio is passed to resizeTexture.
|
||||
- **BREAKING** **FIX**: (flutter) pass pixelRatio to createTexture.
|
||||
|
||||
#### `thermion_flutter_web` - `v0.1.0-dev.1.0`
|
||||
|
||||
- **FIX**: (flutter/web) use window.devicePixelRatio for viewport.
|
||||
- **FEAT**: (flutter) (web) use options to determine whether to create canvas, and set fixed position + offset.
|
||||
- **FEAT**: add ThermionFlutterOptions classes, rename interface parameter for offsetTop and ensure pixelRatio is passed to resizeTexture.
|
||||
@@ -244,35 +489,7 @@ Packages with other changes:
|
||||
- **BREAKING** **FEAT**: resize canvas on web.
|
||||
|
||||
|
||||
## 2024-07-23
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`thermion_dart` - `v0.1.3`](#thermion_dart---v013)
|
||||
- [`thermion_flutter_ffi` - `v0.1.0+12`](#thermion_flutter_ffi---v01012)
|
||||
- [`thermion_flutter_web` - `v0.0.3`](#thermion_flutter_web---v003)
|
||||
- [`thermion_flutter_platform_interface` - `v0.1.0+11`](#thermion_flutter_platform_interface---v01011)
|
||||
- [`thermion_flutter` - `v0.1.1+13`](#thermion_flutter---v01113)
|
||||
|
||||
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+11`
|
||||
- `thermion_flutter` - `v0.1.1+13`
|
||||
|
||||
---
|
||||
|
||||
#### `thermion_dart` - `v0.1.3`
|
||||
|
||||
## v0.1.3
|
||||
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||
- **FIX**: web/JS bool checks need to compare to int.
|
||||
- **FIX**: shadow JS<->WASM bridge methods.
|
||||
|
||||
1
Makefile
1
Makefile
@@ -12,6 +12,7 @@ flutter-example-web: dart-web-clean dart-web
|
||||
flutter-example-macos:
|
||||
cd thermion_flutter_federated/thermion_flutter/example/web && flutter run -d macos
|
||||
swift-bindings:
|
||||
swiftc -c thermion_flutter/thermion_flutter/macos/Classes/ThermionTexture.swift -module-name swift_module -emit-objc-header-path thermion_dart/native/include/generated/ThermionTextureSwiftObjCAPI.h -emit-library -o thermion_dart/test/libThermionTextureSwift.dylib
|
||||
cd thermion_dart/ && dart --enable-experiment=native-assets run ffigen --config ffigen/swift.yaml
|
||||
bindings:
|
||||
cd thermion_dart/ && dart --enable-experiment=native-assets run ffigen --config ffigen/native.yaml
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
## Android
|
||||
|
||||
### Min SDK version
|
||||
|
||||
Thermion requires Android SDK version 22, so change your `app/android/build.gradle` to match this version or higher:
|
||||
|
||||
```groovy
|
||||
defaultConfig {
|
||||
...
|
||||
minSdk = 22
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Shrink/Minify Resources
|
||||
|
||||
In release mode, you must add the following to your `app/build.gradle`:
|
||||
|
||||
```
|
||||
|
||||
@@ -13,6 +13,10 @@ material {
|
||||
{
|
||||
type : int,
|
||||
name : baseColorIndex
|
||||
},
|
||||
{
|
||||
type : float2,
|
||||
name : uvScale
|
||||
}
|
||||
],
|
||||
depthWrite : true,
|
||||
@@ -21,7 +25,7 @@ material {
|
||||
blending: opaque,
|
||||
culling: none,
|
||||
instanced: false,
|
||||
vertexDomain: object
|
||||
vertexDomain: object,
|
||||
}
|
||||
|
||||
fragment {
|
||||
|
||||
@@ -1,3 +1,74 @@
|
||||
## 0.2.1-dev.0.0.8
|
||||
|
||||
- **FIX**: move ThermionWin32.h to include.
|
||||
|
||||
## 0.2.1-dev.0.0.7
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.7`.
|
||||
|
||||
## 0.2.1-dev.0.0.6
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.6`.
|
||||
|
||||
## 0.2.1-dev.0.0.5
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.5`.
|
||||
|
||||
## 0.2.1-dev.0.0.4
|
||||
|
||||
## 0.2.1-dev.0.0.3
|
||||
|
||||
- Bump "thermion_dart" to `0.2.1-dev.0.0.3`.
|
||||
|
||||
## 0.2.1-dev.0.0.2
|
||||
|
||||
## 0.2.1-dev.0.0.1
|
||||
|
||||
## 0.2.1-dev.0.0.0
|
||||
|
||||
- y
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
|
||||
|
||||
## 0.2.0-dev.8.0.0
|
||||
|
||||
> Note: This release has breaking changes.
|
||||
|
||||
- **REFACTOR**: continual refactor to support multiple render targets.
|
||||
- **FEAT**: camera and resizing improvements.
|
||||
- **FEAT**: support multiple ThermionWidget on Android.
|
||||
- **FEAT**: use imported texture on iOS.
|
||||
- **FEAT**: working implementation of multiple widgets on macos.
|
||||
- **FEAT**: more work on multiple views/swapchains.
|
||||
- **FEAT**: add setParameterFloat2 method.
|
||||
- **FEAT**: add setParameterFloat2 method.
|
||||
- **FEAT**: add uvScale to unlit material.
|
||||
- **FEAT**: add ThirdPersonCameraDelegate.
|
||||
- **FEAT**: set camera model matrix directly.
|
||||
- **FEAT**: expose more camera methods.
|
||||
- **BREAKING** **REFACTOR**: refactor to support multiple Views/Render Targets.
|
||||
- **BREAKING** **REFACTOR**: remove RenderThread methods no longer needed.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FIX**: replace queuePosition/Rotation with queueTransforms.
|
||||
- **BREAKING** **FEAT**: big refactor to support multiple swapchains.
|
||||
- **BREAKING** **FEAT**: set baseColorIndex to -1 by default in unlit materialss.
|
||||
|
||||
## 0.2.0-dev.7.0
|
||||
|
||||
> Note: This release has breaking changes.
|
||||
|
||||
- **BREAKING** **FIX**: fix min SDK for thermion_dart.
|
||||
|
||||
## 0.2.0-dev.6.0
|
||||
|
||||
> Note: This release has breaking changes.
|
||||
|
||||
- **BREAKING** **CHORE**: cleanup deleted export.
|
||||
|
||||
## 0.2.0-dev.5.0
|
||||
|
||||
> Note: This release has breaking changes.
|
||||
|
||||
30
thermion_dart/extras/windows/CMakeLists.txt
Normal file
30
thermion_dart/extras/windows/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
set(PROJECT_NAME "thermion_windows")
|
||||
project(${PROJECT_NAME} LANGUAGES C CXX)
|
||||
|
||||
cmake_policy(VERSION 3.14...3.25)
|
||||
|
||||
add_compile_definitions(WGL_USE_BACKING_WINDOW)
|
||||
add_compile_definitions(UNICODE)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED
|
||||
"thermion_window.cpp"
|
||||
)
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/../../../../thermion_dart/native/include/filament"
|
||||
"${CMAKE_SOURCE_DIR}/../../../../thermion_dart/native/include"
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Shlwapi
|
||||
opengl32
|
||||
dwmapi
|
||||
comctl32
|
||||
)
|
||||
|
||||
244
thermion_dart/extras/windows/thermion_window.cpp
Normal file
244
thermion_dart/extras/windows/thermion_window.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
#include "thermion_window.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <ShObjIdl.h>
|
||||
|
||||
#pragma comment(lib, "dwmapi.lib")
|
||||
#pragma comment(lib, "comctl32.lib")
|
||||
|
||||
namespace thermion {
|
||||
|
||||
static constexpr auto kClassName = L"THERMION_WINDOW";
|
||||
static constexpr auto kWindowName = L"thermion_window";
|
||||
static bool was_window_hidden_due_to_minimize_ = false;
|
||||
static WPARAM last_wm_size_wparam_ = SIZE_RESTORED;
|
||||
uint64_t last_thread_time_ = 0;
|
||||
static constexpr auto kNativeViewPositionAndShowDelay = 300;
|
||||
|
||||
typedef enum _WINDOWCOMPOSITIONATTRIB {
|
||||
WCA_UNDEFINED = 0,
|
||||
WCA_NCRENDERING_ENABLED = 1,
|
||||
WCA_NCRENDERING_POLICY = 2,
|
||||
WCA_TRANSITIONS_FORCEDISABLED = 3,
|
||||
WCA_ALLOW_NCPAINT = 4,
|
||||
WCA_CAPTION_BUTTON_BOUNDS = 5,
|
||||
WCA_NONCLIENT_RTL_LAYOUT = 6,
|
||||
WCA_FORCE_ICONIC_REPRESENTATION = 7,
|
||||
WCA_EXTENDED_FRAME_BOUNDS = 8,
|
||||
WCA_HAS_ICONIC_BITMAP = 9,
|
||||
WCA_THEME_ATTRIBUTES = 10,
|
||||
WCA_NCRENDERING_EXILED = 11,
|
||||
WCA_NCADORNMENTINFO = 12,
|
||||
WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
|
||||
WCA_VIDEO_OVERLAY_ACTIVE = 14,
|
||||
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
|
||||
WCA_DISALLOW_PEEK = 16,
|
||||
WCA_CLOAK = 17,
|
||||
WCA_CLOAKED = 18,
|
||||
WCA_ACCENT_POLICY = 19,
|
||||
WCA_FREEZE_REPRESENTATION = 20,
|
||||
WCA_EVER_UNCLOAKED = 21,
|
||||
WCA_VISUAL_OWNER = 22,
|
||||
WCA_HOLOGRAPHIC = 23,
|
||||
WCA_EXCLUDED_FROM_DDA = 24,
|
||||
WCA_PASSIVEUPDATEMODE = 25,
|
||||
WCA_USEDARKMODECOLORS = 26,
|
||||
WCA_LAST = 27
|
||||
} WINDOWCOMPOSITIONATTRIB;
|
||||
|
||||
typedef struct _WINDOWCOMPOSITIONATTRIBDATA {
|
||||
WINDOWCOMPOSITIONATTRIB Attrib;
|
||||
PVOID pvData;
|
||||
SIZE_T cbData;
|
||||
} WINDOWCOMPOSITIONATTRIBDATA;
|
||||
|
||||
typedef enum _ACCENT_STATE {
|
||||
ACCENT_DISABLED = 0,
|
||||
ACCENT_ENABLE_GRADIENT = 1,
|
||||
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||
ACCENT_ENABLE_BLURBEHIND = 3,
|
||||
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
|
||||
ACCENT_ENABLE_HOSTBACKDROP = 5,
|
||||
ACCENT_INVALID_STATE = 6
|
||||
} ACCENT_STATE;
|
||||
|
||||
typedef struct _ACCENT_POLICY {
|
||||
ACCENT_STATE AccentState;
|
||||
DWORD AccentFlags;
|
||||
DWORD GradientColor;
|
||||
DWORD AnimationId;
|
||||
} ACCENT_POLICY;
|
||||
|
||||
typedef BOOL(WINAPI* _GetWindowCompositionAttribute)(
|
||||
HWND, WINDOWCOMPOSITIONATTRIBDATA*);
|
||||
typedef BOOL(WINAPI* _SetWindowCompositionAttribute)(
|
||||
HWND, WINDOWCOMPOSITIONATTRIBDATA*);
|
||||
|
||||
static _SetWindowCompositionAttribute g_set_window_composition_attribute = NULL;
|
||||
static bool g_set_window_composition_attribute_initialized = false;
|
||||
|
||||
typedef LONG NTSTATUS, *PNTSTATUS;
|
||||
#define STATUS_SUCCESS (0x00000000)
|
||||
|
||||
typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||
|
||||
RTL_OSVERSIONINFOW GetWindowsVersion() {
|
||||
HMODULE hmodule = ::GetModuleHandleW(L"ntdll.dll");
|
||||
if (hmodule) {
|
||||
RtlGetVersionPtr rtl_get_version_ptr =
|
||||
(RtlGetVersionPtr)::GetProcAddress(hmodule, "RtlGetVersion");
|
||||
if (rtl_get_version_ptr != nullptr) {
|
||||
RTL_OSVERSIONINFOW rovi = {0};
|
||||
rovi.dwOSVersionInfoSize = sizeof(rovi);
|
||||
if (STATUS_SUCCESS == rtl_get_version_ptr(&rovi)) {
|
||||
return rovi;
|
||||
}
|
||||
}
|
||||
}
|
||||
RTL_OSVERSIONINFOW rovi = {0};
|
||||
return rovi;
|
||||
}
|
||||
|
||||
void SetWindowComposition(HWND window, int32_t accent_state,
|
||||
int32_t gradient_color) {
|
||||
// TODO: Look for a better available API.
|
||||
if (GetWindowsVersion().dwBuildNumber >= 18362) {
|
||||
if (!g_set_window_composition_attribute_initialized) {
|
||||
auto user32 = ::GetModuleHandleA("user32.dll");
|
||||
if (user32) {
|
||||
g_set_window_composition_attribute =
|
||||
reinterpret_cast<_SetWindowCompositionAttribute>(
|
||||
::GetProcAddress(user32, "SetWindowCompositionAttribute"));
|
||||
if (g_set_window_composition_attribute) {
|
||||
g_set_window_composition_attribute_initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ACCENT_POLICY accent = {static_cast<ACCENT_STATE>(accent_state), 2,
|
||||
static_cast<DWORD>(gradient_color), 0};
|
||||
WINDOWCOMPOSITIONATTRIBDATA data;
|
||||
data.Attrib = WCA_ACCENT_POLICY;
|
||||
data.pvData = &accent;
|
||||
data.cbData = sizeof(accent);
|
||||
g_set_window_composition_attribute(window, &data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LRESULT CALLBACK FilamentWindowProc(HWND const window, UINT const message,
|
||||
WPARAM const wparam,
|
||||
LPARAM const lparam) noexcept {
|
||||
switch (message) {
|
||||
std::cout << message <<std::endl;
|
||||
case WM_MOUSEMOVE: {
|
||||
TRACKMOUSEEVENT event;
|
||||
event.cbSize = sizeof(event);
|
||||
event.hwndTrack = window;
|
||||
event.dwFlags = TME_HOVER;
|
||||
event.dwHoverTime = 200;
|
||||
auto user_data = ::GetWindowLongPtr(window, GWLP_USERDATA);
|
||||
if (user_data) {
|
||||
HWND flutterRootWindow = reinterpret_cast<HWND>(user_data);
|
||||
::SetForegroundWindow(flutterRootWindow);
|
||||
LONG ex_style = ::GetWindowLong(flutterRootWindow, GWL_EXSTYLE);
|
||||
ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||
::SetWindowLong(flutterRootWindow, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_ERASEBKGND: {
|
||||
HDC hdc = (HDC)wparam;
|
||||
RECT rect;
|
||||
GetClientRect(window, &rect);
|
||||
|
||||
// Get the ThermionWindow instance associated with this window
|
||||
ThermionWindow* thermionWindow = reinterpret_cast<ThermionWindow*>(
|
||||
GetWindowLongPtr(window, GWLP_USERDATA));
|
||||
|
||||
if (thermionWindow) {
|
||||
HBRUSH brush = CreateSolidBrush(RGB(0, 0, 255));
|
||||
FillRect(hdc, &rect, brush);
|
||||
DeleteObject(brush);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_SIZE:
|
||||
break;
|
||||
case WM_MOVE:
|
||||
case WM_MOVING:
|
||||
case WM_ACTIVATE:
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
// NativeViewCore::GetInstance()->SetHitTestBehavior(0);
|
||||
auto user_data = ::GetWindowLongPtr(window, GWLP_USERDATA);
|
||||
if (user_data) {
|
||||
HWND flutterRootWindow = reinterpret_cast<HWND>(user_data);
|
||||
::SetForegroundWindow(flutterRootWindow);
|
||||
// NativeViewCore::GetInstance()->SetHitTestBehavior(0);
|
||||
LONG ex_style = ::GetWindowLong(flutterRootWindow, GWL_EXSTYLE);
|
||||
ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||
::SetWindowLong(flutterRootWindow, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ::DefWindowProc(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
ThermionWindow::ThermionWindow(int width,
|
||||
int height,
|
||||
int left,
|
||||
int top) : _width(width), _height(height), _left(left), _top(top) {
|
||||
// create the HWND for Filament
|
||||
auto window_class = WNDCLASSEX{};
|
||||
::SecureZeroMemory(&window_class, sizeof(window_class));
|
||||
window_class.cbSize = sizeof(window_class);
|
||||
window_class.style = CS_HREDRAW | CS_VREDRAW;
|
||||
window_class.lpfnWndProc = FilamentWindowProc;
|
||||
window_class.hInstance = 0;
|
||||
window_class.lpszClassName = kClassName;
|
||||
window_class.hCursor = ::LoadCursorW(nullptr, IDC_ARROW);
|
||||
window_class.hbrBackground = ::CreateSolidBrush(RGB(0,255,0));
|
||||
::RegisterClassExW(&window_class);
|
||||
_windowHandle = ::CreateWindow(kClassName, kWindowName, WS_OVERLAPPEDWINDOW,
|
||||
0, 0, _width, _height, nullptr,
|
||||
nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
|
||||
// Disable DWM animations
|
||||
auto disable_window_transitions = TRUE;
|
||||
DwmSetWindowAttribute(_windowHandle, DWMWA_TRANSITIONS_FORCEDISABLED,
|
||||
&disable_window_transitions,
|
||||
sizeof(disable_window_transitions));
|
||||
|
||||
auto style = ::GetWindowLong(_windowHandle, GWL_STYLE);
|
||||
style &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
|
||||
WS_EX_APPWINDOW);
|
||||
::SetWindowLong(_windowHandle, GWL_STYLE, style);
|
||||
|
||||
// // remove taskbar entry for the window we created
|
||||
// ITaskbarList3* taskbar = nullptr;
|
||||
// ::CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER,
|
||||
// IID_PPV_ARGS(&taskbar));
|
||||
// taskbar->DeleteTab(_windowHandle);
|
||||
// taskbar->Release();
|
||||
::ShowWindow(_windowHandle, SW_SHOW);
|
||||
UpdateWindow(_windowHandle);
|
||||
}
|
||||
|
||||
void ThermionWindow::Resize(int width, int height, int left, int top) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_left = left;
|
||||
_top = top;
|
||||
}
|
||||
|
||||
HWND ThermionWindow::GetHandle() { return _windowHandle; }
|
||||
} // namespace thermion_flutter
|
||||
57
thermion_dart/extras/windows/thermion_window.h
Normal file
57
thermion_dart/extras/windows/thermion_window.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef IS_DLL
|
||||
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
|
||||
#else
|
||||
#define EMSCRIPTEN_KEEPALIVE __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace thermion {
|
||||
|
||||
///
|
||||
/// Instantiating a ThermionWindow creates a HWND that can be passed
|
||||
/// to Filament to create a swapchain.
|
||||
///
|
||||
///
|
||||
class ThermionWindow {
|
||||
public:
|
||||
ThermionWindow(
|
||||
int width,
|
||||
int height,
|
||||
int left,
|
||||
int top);
|
||||
HWND GetHandle();
|
||||
void Resize(int width, int height, int left, int top);
|
||||
private:
|
||||
HWND _windowHandle;
|
||||
uint32_t _width = 0;
|
||||
uint32_t _height = 0;
|
||||
uint32_t _left = 0;
|
||||
uint32_t _top = 0;
|
||||
};
|
||||
|
||||
static ThermionWindow* _window;
|
||||
|
||||
extern "C" {
|
||||
EMSCRIPTEN_KEEPALIVE intptr_t create_thermion_window(int width, int height, int left, int top) {
|
||||
_window = new ThermionWindow(width, height, left, top);
|
||||
return (intptr_t)_window->GetHandle();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void update() {
|
||||
MSG msg;
|
||||
if(GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,12 +1,18 @@
|
||||
output: '../lib/thermion_dart/viewer/ffi/thermion_dart.g.dart'
|
||||
output: '../lib/src/viewer/src/ffi/src/thermion_dart.g.dart'
|
||||
headers:
|
||||
entry-points:
|
||||
- '../native/include/ThermionDartRenderThreadApi.h'
|
||||
- '../native/include/ThermionDartApi.h'
|
||||
- '../native/include/TView.h'
|
||||
- '../native/include/TCamera.h'
|
||||
- '../native/include/TGizmo.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
include-directives:
|
||||
- '../native/include/ThermionDartRenderThreadApi.h'
|
||||
- '../native/include/ThermionDartApi.h'
|
||||
- '../native/include/TView.h'
|
||||
- '../native/include/TCamera.h'
|
||||
- '../native/include/TGizmo.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
- '../native/include/APIBoundaryTypes.h'
|
||||
ffi-native:
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
name: ThermionDartTexture
|
||||
description: Bindings for ThermionDartTexture.
|
||||
name: ThermionTextureSwift
|
||||
description: Bindings for ThermionTexture.
|
||||
language: objc
|
||||
output: 'lib/thermion_dart/swift/swift_bindings.g.dart'
|
||||
output: '../lib/src/swift/swift_bindings.g.dart'
|
||||
exclude-all-by-default: true
|
||||
objc-interfaces:
|
||||
include:
|
||||
- 'ThermionDartTexture'
|
||||
- 'ThermionTextureSwift'
|
||||
module:
|
||||
'ThermionDartTexture': 'thermion_dart_texture'
|
||||
'ThermionTextureSwift': 'swift_module'
|
||||
headers:
|
||||
entry-points:
|
||||
- 'native/lib/macos/swift/ThermionDartTexture.h'
|
||||
- '../native/include/generated/ThermionTextureSwiftObjCAPI.h'
|
||||
preamble: |
|
||||
// ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field, return_of_invalid_type, void_checks, annotate_overrides, no_leading_underscores_for_local_identifiers, library_private_types_in_public_apia
|
||||
@@ -32,19 +32,14 @@ void main(List<String> args) async {
|
||||
final name = "thermion_dart.dart";
|
||||
final libUri = config.outputDirectory
|
||||
.resolve(config.targetOS.libraryFileName(name, linkMode));
|
||||
output.addAssets(
|
||||
[
|
||||
NativeCodeAsset(
|
||||
output.addAsset(NativeCodeAsset(
|
||||
package: config.packageName,
|
||||
name: name,
|
||||
file: libUri,
|
||||
linkMode: linkMode,
|
||||
os: config.targetOS,
|
||||
architecture: config.dryRun ? null : config.targetArchitecture,
|
||||
)
|
||||
],
|
||||
linkInPackage: null,
|
||||
);
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,7 +53,7 @@ void main(List<String> args) async {
|
||||
.map((f) => f.path)
|
||||
.toList();
|
||||
sources.addAll([
|
||||
"${config.packageRoot.toFilePath()}/native/include/material/gizmo.c",
|
||||
"${config.packageRoot.toFilePath()}/native/include/material/gizmo_material.c",
|
||||
"${config.packageRoot.toFilePath()}/native/include/material/image.c",
|
||||
"${config.packageRoot.toFilePath()}/native/include/material/grid.c",
|
||||
"${config.packageRoot.toFilePath()}/native/include/material/unlit.c",
|
||||
@@ -92,7 +87,6 @@ void main(List<String> args) async {
|
||||
"basis_transcoder"
|
||||
];
|
||||
|
||||
|
||||
if (platform == "windows") {
|
||||
libDir = Directory(libDir).uri.toFilePath();
|
||||
libs = libs.map((lib) => "${libDir}${lib}.lib").toList();
|
||||
@@ -118,7 +112,12 @@ void main(List<String> args) async {
|
||||
defines["WIN32"] = "1";
|
||||
defines["_DEBUG"] = "1";
|
||||
defines["_DLL"] = "1";
|
||||
flags.addAll(["/std:c++20", "/MDd"]);
|
||||
flags.addAll([
|
||||
"/std:c++20",
|
||||
"/MDd",
|
||||
"/VERBOSE",
|
||||
...defines.keys.map((k) => "/D$k=${defines[k]}").toList()
|
||||
]);
|
||||
}
|
||||
|
||||
if (platform == "ios") {
|
||||
@@ -149,16 +148,26 @@ void main(List<String> args) async {
|
||||
name: packageName,
|
||||
language: Language.cpp,
|
||||
assetName: 'thermion_dart.dart',
|
||||
sources: sources,
|
||||
includes: ['native/include', 'native/include/filament'],
|
||||
defines: defines,
|
||||
sources: platform == "windows" ? [] : sources,
|
||||
includes: platform == "windows"
|
||||
? []
|
||||
: ['native/include', 'native/include/filament'],
|
||||
defines: platform == "windows" ? {} : defines,
|
||||
flags: [
|
||||
if (platform == "macos") '-mmacosx-version-min=13.0',
|
||||
if (platform == "ios") '-mios-version-min=13.0',
|
||||
...flags,
|
||||
...frameworks,
|
||||
...libs.map((lib) => "-l$lib"),
|
||||
"-L$libDir",
|
||||
if (platform != "windows") ...libs.map((lib) => "-l$lib"),
|
||||
if (platform != "windows") "-L$libDir",
|
||||
if (platform == "windows") ...[
|
||||
"/I${config.packageRoot.toFilePath()}\\native\\include",
|
||||
"/I${config.packageRoot.toFilePath()}native\\include\\filament",
|
||||
...sources,
|
||||
'/link',
|
||||
"/LIBPATH:$libDir",
|
||||
'/DLL',
|
||||
]
|
||||
],
|
||||
dartBuildFiles: ['hook/build.dart'],
|
||||
);
|
||||
@@ -180,14 +189,21 @@ void main(List<String> args) async {
|
||||
|
||||
var compilerPath = config.cCompiler.compiler!.path;
|
||||
|
||||
if(Platform.isWindows && compilerPath.startsWith("/")) {
|
||||
if (Platform.isWindows && compilerPath.startsWith("/")) {
|
||||
compilerPath = compilerPath.substring(1);
|
||||
}
|
||||
|
||||
var ndkRoot = File(compilerPath).parent.parent.uri.toFilePath(windows:true);
|
||||
var ndkRoot =
|
||||
File(compilerPath).parent.parent.uri.toFilePath(windows: true);
|
||||
|
||||
var stlPath =
|
||||
File([ndkRoot, "sysroot", "usr", "lib", archExtension, "libc++_shared.so"].join(Platform.pathSeparator));
|
||||
var stlPath = File([
|
||||
ndkRoot,
|
||||
"sysroot",
|
||||
"usr",
|
||||
"lib",
|
||||
archExtension,
|
||||
"libc++_shared.so"
|
||||
].join(Platform.pathSeparator));
|
||||
output.addAsset(NativeCodeAsset(
|
||||
package: "thermion_dart",
|
||||
name: "libc++_shared.so",
|
||||
@@ -201,7 +217,7 @@ void main(List<String> args) async {
|
||||
if (config.targetOS == "windows") {
|
||||
output.addAsset(
|
||||
NativeCodeAsset(
|
||||
package: "thermion_dart",
|
||||
package: config.packageName,
|
||||
name: "thermion_dart.dll",
|
||||
linkMode: DynamicLoadingBundled(),
|
||||
os: config.targetOS,
|
||||
|
||||
7
thermion_dart/lib/src/input/input.dart
Normal file
7
thermion_dart/lib/src/input/input.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
library;
|
||||
|
||||
export 'src/input_handler.dart';
|
||||
export 'src/delegates.dart';
|
||||
export 'src/delegate_gesture_handler.dart';
|
||||
export 'src/implementations/default_pick_delegate.dart';
|
||||
export 'src/implementations/third_person_camera_delegate.dart';
|
||||
282
thermion_dart/lib/src/input/src/delegate_gesture_handler.dart
Normal file
282
thermion_dart/lib/src/input/src/delegate_gesture_handler.dart
Normal file
@@ -0,0 +1,282 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import 'implementations/fixed_orbit_camera_rotation_delegate.dart';
|
||||
import 'implementations/free_flight_camera_delegate.dart';
|
||||
|
||||
class DelegateInputHandler implements InputHandler {
|
||||
final ThermionViewer viewer;
|
||||
|
||||
Stream<List<InputType>> get gestures => _gesturesController.stream;
|
||||
final _gesturesController = StreamController<List<InputType>>.broadcast();
|
||||
|
||||
Stream get cameraUpdated => _cameraUpdatedController.stream;
|
||||
final _cameraUpdatedController = StreamController.broadcast();
|
||||
|
||||
final _logger = Logger("DelegateInputHandler");
|
||||
|
||||
InputHandlerDelegate? transformDelegate;
|
||||
PickDelegate? pickDelegate;
|
||||
|
||||
final Set<PhysicalKey> _pressedKeys = {};
|
||||
|
||||
final _inputDeltas = <InputType, Vector3>{};
|
||||
|
||||
Map<InputType, InputAction> _actions = {
|
||||
InputType.LMB_HOLD_AND_MOVE: InputAction.TRANSLATE,
|
||||
InputType.SCALE1: InputAction.TRANSLATE,
|
||||
InputType.SCALE2: InputAction.ZOOM,
|
||||
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
||||
InputType.SCROLLWHEEL: InputAction.TRANSLATE,
|
||||
InputType.POINTER_MOVE: InputAction.NONE,
|
||||
InputType.KEYDOWN_W: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_S: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_A: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_D: InputAction.TRANSLATE,
|
||||
};
|
||||
|
||||
final _axes = <InputType, Matrix3>{};
|
||||
|
||||
void setTransformForAction(InputType inputType, Matrix3 transform) {
|
||||
_axes[inputType] = transform;
|
||||
}
|
||||
|
||||
DelegateInputHandler({
|
||||
required this.viewer,
|
||||
required this.transformDelegate,
|
||||
this.pickDelegate,
|
||||
Map<InputType, InputAction>? actions,
|
||||
}) {
|
||||
if (actions != null) {
|
||||
_actions = actions;
|
||||
}
|
||||
|
||||
for (var gestureType in InputType.values) {
|
||||
_inputDeltas[gestureType] = Vector3.zero();
|
||||
}
|
||||
|
||||
viewer.registerRequestFrameHook(process);
|
||||
}
|
||||
|
||||
factory DelegateInputHandler.fixedOrbit(ThermionViewer viewer,
|
||||
{double minimumDistance = 10.0,
|
||||
Future<double?> Function(Vector3)? getDistanceToTarget,
|
||||
ThermionEntity? entity,
|
||||
PickDelegate? pickDelegate}) =>
|
||||
DelegateInputHandler(
|
||||
viewer: viewer,
|
||||
pickDelegate: pickDelegate,
|
||||
transformDelegate: FixedOrbitRotateInputHandlerDelegate(viewer,
|
||||
getDistanceToTarget: getDistanceToTarget,
|
||||
minimumDistance: minimumDistance),
|
||||
actions: {
|
||||
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
||||
InputType.SCROLLWHEEL: InputAction.TRANSLATE
|
||||
});
|
||||
|
||||
factory DelegateInputHandler.flight(ThermionViewer viewer,
|
||||
{PickDelegate? pickDelegate,
|
||||
bool freeLook = false,
|
||||
double panSensitivity = 0.1,
|
||||
double movementSensitivity = 0.1,
|
||||
double rotateSensitivity = 0.01,
|
||||
double? clampY,
|
||||
ThermionEntity? entity}) =>
|
||||
DelegateInputHandler(
|
||||
viewer: viewer,
|
||||
pickDelegate: pickDelegate,
|
||||
transformDelegate: FreeFlightInputHandlerDelegate(viewer,
|
||||
clampY: clampY,
|
||||
entity: entity,
|
||||
rotationSensitivity: rotateSensitivity,
|
||||
panSensitivity: panSensitivity,
|
||||
movementSensitivity: movementSensitivity),
|
||||
actions: {
|
||||
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
||||
InputType.SCROLLWHEEL: InputAction.TRANSLATE,
|
||||
InputType.LMB_HOLD_AND_MOVE: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_A: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_W: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_S: InputAction.TRANSLATE,
|
||||
InputType.KEYDOWN_D: InputAction.TRANSLATE,
|
||||
InputType.SCALE1: InputAction.TRANSLATE,
|
||||
InputType.SCALE2: InputAction.ZOOM,
|
||||
if (freeLook) InputType.POINTER_MOVE: InputAction.ROTATE,
|
||||
});
|
||||
|
||||
bool _processing = false;
|
||||
Future<void> process() async {
|
||||
_processing = true;
|
||||
for (var gestureType in _inputDeltas.keys) {
|
||||
var vector = _inputDeltas[gestureType]!;
|
||||
var action = _actions[gestureType];
|
||||
if (action == null) {
|
||||
continue;
|
||||
}
|
||||
final transform = _axes[gestureType];
|
||||
if (transform != null) {
|
||||
vector = transform * vector;
|
||||
}
|
||||
|
||||
await transformDelegate?.queue(action, vector);
|
||||
}
|
||||
final keyTypes = <InputType>[];
|
||||
for (final key in _pressedKeys) {
|
||||
InputAction? keyAction;
|
||||
InputType? keyType = null;
|
||||
Vector3? vector;
|
||||
|
||||
switch (key) {
|
||||
case PhysicalKey.W:
|
||||
keyType = InputType.KEYDOWN_W;
|
||||
vector = Vector3(0, 0, -1);
|
||||
break;
|
||||
case PhysicalKey.A:
|
||||
keyType = InputType.KEYDOWN_A;
|
||||
vector = Vector3(-1, 0, 0);
|
||||
break;
|
||||
case PhysicalKey.S:
|
||||
keyType = InputType.KEYDOWN_S;
|
||||
vector = Vector3(0, 0, 1);
|
||||
break;
|
||||
case PhysicalKey.D:
|
||||
keyType = InputType.KEYDOWN_D;
|
||||
vector = Vector3(1, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (keyType != null) {
|
||||
keyAction = _actions[keyType];
|
||||
|
||||
if (keyAction != null) {
|
||||
var transform = _axes[keyAction];
|
||||
if (transform != null) {
|
||||
vector = transform * vector;
|
||||
}
|
||||
transformDelegate?.queue(keyAction, vector!);
|
||||
keyTypes.add(keyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await transformDelegate?.execute();
|
||||
var updates = _inputDeltas.keys.followedBy(keyTypes).toList();
|
||||
if (updates.isNotEmpty) {
|
||||
_gesturesController.add(updates);
|
||||
_cameraUpdatedController.add(true);
|
||||
}
|
||||
|
||||
_inputDeltas.clear();
|
||||
_processing = false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onPointerDown(Vector2 localPosition, bool isMiddle) async {
|
||||
if (!isMiddle) {
|
||||
final action = _actions[InputType.LMB_DOWN];
|
||||
switch (action) {
|
||||
case InputAction.PICK:
|
||||
pickDelegate?.pick(localPosition);
|
||||
default:
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onPointerMove(
|
||||
Vector2 localPosition, Vector2 delta, bool isMiddle) async {
|
||||
if (_processing) {
|
||||
return;
|
||||
}
|
||||
if (isMiddle) {
|
||||
_inputDeltas[InputType.MMB_HOLD_AND_MOVE] =
|
||||
(_inputDeltas[InputType.MMB_HOLD_AND_MOVE] ?? Vector3.zero()) +
|
||||
Vector3(delta.x, delta.y, 0.0);
|
||||
} else {
|
||||
_inputDeltas[InputType.LMB_HOLD_AND_MOVE] =
|
||||
(_inputDeltas[InputType.LMB_HOLD_AND_MOVE] ?? Vector3.zero()) +
|
||||
Vector3(delta.x, delta.y, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onPointerUp(bool isMiddle) async {}
|
||||
|
||||
@override
|
||||
Future<void> onPointerHover(Vector2 localPosition, Vector2 delta) async {
|
||||
if (_processing) {
|
||||
return;
|
||||
}
|
||||
_inputDeltas[InputType.POINTER_MOVE] =
|
||||
(_inputDeltas[InputType.POINTER_MOVE] ?? Vector3.zero()) +
|
||||
Vector3(delta.x, delta.y, 0.0);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onPointerScroll(
|
||||
Vector2 localPosition, double scrollDelta) async {
|
||||
if (_processing) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
_inputDeltas[InputType.SCROLLWHEEL] =
|
||||
(_inputDeltas[InputType.SCROLLWHEEL] ?? Vector3.zero()) +
|
||||
Vector3(0, 0, scrollDelta > 0 ? 1 : -1);
|
||||
} catch (e) {
|
||||
_logger.warning("Error during scroll accumulation: $e");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future dispose() async {
|
||||
viewer.unregisterRequestFrameHook(process);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get initialized => viewer.initialized;
|
||||
|
||||
@override
|
||||
void setActionForType(InputType gestureType, InputAction gestureAction) {
|
||||
_actions[gestureType] = gestureAction;
|
||||
}
|
||||
|
||||
@override
|
||||
InputAction? getActionForType(InputType gestureType) {
|
||||
return _actions[gestureType];
|
||||
}
|
||||
|
||||
void keyDown(PhysicalKey key) {
|
||||
_pressedKeys.add(key);
|
||||
}
|
||||
|
||||
void keyUp(PhysicalKey key) {
|
||||
_pressedKeys.remove(key);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onScaleEnd(int pointerCount) async {}
|
||||
|
||||
@override
|
||||
Future<void> onScaleStart(Vector2 localPosition, int pointerCount) async {
|
||||
// noop
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onScaleUpdate(Vector2 focalPoint, Vector2 focalPointDelta,
|
||||
double horizontalScale, double verticalScale, double scale, int pointerCount) async {
|
||||
if (pointerCount == 1) {
|
||||
_inputDeltas[InputType.SCALE1] =
|
||||
Vector3(focalPointDelta.x, focalPointDelta.y, 0);
|
||||
} else if (pointerCount == 2) {
|
||||
_inputDeltas[InputType.SCALE2] =
|
||||
Vector3(0, 0, max(horizontalScale, verticalScale));
|
||||
} else {
|
||||
throw UnimplementedError("Only pointerCount <= 2 supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
27
thermion_dart/lib/src/input/src/delegates.dart
Normal file
27
thermion_dart/lib/src/input/src/delegates.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import 'input_handler.dart';
|
||||
|
||||
abstract class InputHandlerDelegate {
|
||||
Future queue(InputAction action, Vector3? delta);
|
||||
Future execute();
|
||||
}
|
||||
|
||||
abstract class VelocityDelegate {
|
||||
Vector2? get velocity;
|
||||
|
||||
void updateVelocity(Vector2 delta);
|
||||
|
||||
void startDeceleration();
|
||||
|
||||
void stopDeceleration();
|
||||
|
||||
void dispose() {
|
||||
stopDeceleration();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PickDelegate {
|
||||
const PickDelegate();
|
||||
void pick(Vector2 location);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// import 'dart:async';
|
||||
// import 'dart:ui';
|
||||
|
||||
// import 'package:flutter/services.dart';
|
||||
// import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
// import 'package:thermion_dart/thermion_dart/input/delegates.dart';
|
||||
// import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
// class DefaultKeyboardCameraFlightDelegate
|
||||
// {
|
||||
// final ThermionViewer viewer;
|
||||
|
||||
// static const double _panSensitivity = 0.005;
|
||||
// static const double _keyMoveSensitivity = 0.1;
|
||||
|
||||
// final Map<PhysicalKeyboardKey, bool> _pressedKeys = {};
|
||||
// Timer? _moveTimer;
|
||||
|
||||
// DefaultKeyboardCameraFlightDelegate(this.viewer) {
|
||||
// _startMoveLoop();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> panCamera(Offset delta, Vector2? velocity) async {
|
||||
// double deltaX = delta.dx;
|
||||
// double deltaY = delta.dy;
|
||||
// deltaX *= _panSensitivity * viewer.pixelRatio;
|
||||
// deltaY *= _panSensitivity * viewer.pixelRatio;
|
||||
|
||||
// await _moveCamera(deltaX, deltaY, 0);
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onKeypress(PhysicalKeyboardKey key) async {
|
||||
// _pressedKeys[key] = true;
|
||||
// }
|
||||
|
||||
// // New method to handle key release
|
||||
// Future<void> onKeyRelease(PhysicalKeyboardKey key) async {
|
||||
// _pressedKeys.remove(key);
|
||||
// }
|
||||
|
||||
// void _startMoveLoop() {
|
||||
// _moveTimer = Timer.periodic(
|
||||
// Duration(milliseconds: 16), (_) => _processKeyboardInput());
|
||||
// }
|
||||
|
||||
// Future<void> _processKeyboardInput() async {
|
||||
// double dx = 0, dy = 0, dz = 0;
|
||||
|
||||
// if (_pressedKeys[PhysicalKeyboardKey.keyW] == true)
|
||||
// dz += _keyMoveSensitivity;
|
||||
// if (_pressedKeys[PhysicalKeyboardKey.keyS] == true)
|
||||
// dz -= _keyMoveSensitivity;
|
||||
// if (_pressedKeys[PhysicalKeyboardKey.keyA] == true)
|
||||
// dx -= _keyMoveSensitivity;
|
||||
// if (_pressedKeys[PhysicalKeyboardKey.keyD] == true)
|
||||
// dx += _keyMoveSensitivity;
|
||||
|
||||
// if (dx != 0 || dy != 0 || dz != 0) {
|
||||
// await _moveCamera(dx, dy, dz);
|
||||
// }
|
||||
// // Removed _pressedKeys.clear(); from here
|
||||
// }
|
||||
|
||||
// Future<void> _moveCamera(double dx, double dy, double dz) async {
|
||||
// Matrix4 currentModelMatrix = await viewer.getCameraModelMatrix();
|
||||
// Vector3 currentPosition = currentModelMatrix.getTranslation();
|
||||
// Quaternion currentRotation =
|
||||
// Quaternion.fromRotation(currentModelMatrix.getRotation());
|
||||
|
||||
// Vector3 forward = Vector3(0, 0, -1)..applyQuaternion(currentRotation);
|
||||
// Vector3 right = Vector3(1, 0, 0)..applyQuaternion(currentRotation);
|
||||
// Vector3 up = Vector3(0, 1, 0)..applyQuaternion(currentRotation);
|
||||
|
||||
// Vector3 moveOffset = right * dx + up * dy + forward * dz;
|
||||
// Vector3 newPosition = currentPosition + moveOffset;
|
||||
|
||||
// Matrix4 newModelMatrix =
|
||||
// Matrix4.compose(newPosition, currentRotation, Vector3(1, 1, 1));
|
||||
// await viewer.setCameraModelMatrix4(newModelMatrix);
|
||||
// }
|
||||
|
||||
// void dispose() {
|
||||
// _moveTimer?.cancel();
|
||||
// }
|
||||
// }
|
||||
@@ -4,12 +4,12 @@
|
||||
// import 'package:thermion_flutter/thermion/widgets/camera/gestures/v2/delegates.dart';
|
||||
// import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
// class DefaultPanCameraDelegate implements PanCameraDelegate {
|
||||
// class DefaultPanInputHandlerDelegate implements PanInputHandlerDelegate {
|
||||
// final ThermionViewer viewer;
|
||||
|
||||
// static const double _panSensitivity = 0.005;
|
||||
|
||||
// DefaultPanCameraDelegate(this.viewer);
|
||||
// DefaultPanInputHandlerDelegate(this.viewer);
|
||||
// static const double _panSensitivity = 0.005;
|
||||
|
||||
// @override
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
class DefaultPickDelegate extends PickDelegate {
|
||||
final ThermionViewer viewer;
|
||||
|
||||
const DefaultPickDelegate(this.viewer);
|
||||
|
||||
@override
|
||||
void pick(Vector2 location) {
|
||||
viewer.pick(location.x.toInt(), location.y.toInt());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
import 'dart:async';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import '../../../viewer/src/shared_types/camera.dart';
|
||||
import '../../../viewer/viewer.dart';
|
||||
import '../../input.dart';
|
||||
import '../input_handler.dart';
|
||||
|
||||
class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||
final ThermionViewer viewer;
|
||||
late Future<Camera> _camera;
|
||||
final double minimumDistance;
|
||||
Future<double?> Function(Vector3)? getDistanceToTarget;
|
||||
|
||||
Vector2 _queuedRotationDelta = Vector2.zero();
|
||||
double _queuedZoomDelta = 0.0;
|
||||
|
||||
static final _up = Vector3(0, 1, 0);
|
||||
Timer? _updateTimer;
|
||||
|
||||
FixedOrbitRotateInputHandlerDelegate(
|
||||
this.viewer, {
|
||||
this.getDistanceToTarget,
|
||||
this.minimumDistance = 10.0,
|
||||
}) {
|
||||
_camera = viewer.getMainCamera().then((Camera cam) async {
|
||||
var viewMatrix = makeViewMatrix(Vector3(0.0, 0, -minimumDistance),
|
||||
Vector3.zero(), Vector3(0.0, 1.0, 0.0));
|
||||
viewMatrix.invert();
|
||||
|
||||
await cam.setTransform(viewMatrix);
|
||||
return cam;
|
||||
});
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_updateTimer?.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> queue(InputAction action, Vector3? delta) async {
|
||||
if (delta == null) return;
|
||||
|
||||
switch (action) {
|
||||
case InputAction.ROTATE:
|
||||
_queuedRotationDelta += Vector2(delta.x, delta.y);
|
||||
break;
|
||||
case InputAction.TRANSLATE:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
case InputAction.PICK:
|
||||
break;
|
||||
case InputAction.NONE:
|
||||
// Do nothing
|
||||
break;
|
||||
case InputAction.ZOOM:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool _executing = false;
|
||||
|
||||
@override
|
||||
Future<void> execute() async {
|
||||
if (_queuedRotationDelta.length2 == 0.0 && _queuedZoomDelta == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_executing) {
|
||||
return;
|
||||
}
|
||||
|
||||
_executing = true;
|
||||
|
||||
final view = await viewer.getViewAt(0);
|
||||
final viewport = await view.getViewport();
|
||||
|
||||
var viewMatrix = await viewer.getCameraViewMatrix();
|
||||
var modelMatrix = await viewer.getCameraModelMatrix();
|
||||
var projectionMatrix = await viewer.getCameraProjectionMatrix();
|
||||
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
||||
Vector3 currentPosition = modelMatrix.getTranslation();
|
||||
|
||||
Vector3 forward = -currentPosition.normalized();
|
||||
|
||||
if (forward.length == 0) {
|
||||
forward = Vector3(0, 0, -1);
|
||||
currentPosition = Vector3(0, 0, minimumDistance);
|
||||
}
|
||||
|
||||
Vector3 right = _up.cross(forward).normalized();
|
||||
Vector3 up = forward.cross(right);
|
||||
|
||||
// Calculate the point where the camera forward ray intersects with the
|
||||
// surface of the target sphere
|
||||
var distanceToTarget =
|
||||
(await getDistanceToTarget?.call(currentPosition)) ?? 0;
|
||||
|
||||
Vector3 intersection =
|
||||
(-forward).scaled(currentPosition.length - distanceToTarget);
|
||||
|
||||
final intersectionInViewSpace = viewMatrix *
|
||||
Vector4(intersection.x, intersection.y, intersection.z, 1.0);
|
||||
final intersectionInClipSpace = projectionMatrix * intersectionInViewSpace;
|
||||
final intersectionInNdcSpace =
|
||||
intersectionInClipSpace / intersectionInClipSpace.w;
|
||||
|
||||
// Calculate new camera position based on rotation
|
||||
final ndcX = 2 * ((-_queuedRotationDelta.x) / viewport.width);
|
||||
final ndcY = 2 * ((_queuedRotationDelta.y) / viewport.height);
|
||||
final ndc = Vector4(ndcX, ndcY, intersectionInNdcSpace.z, 1.0);
|
||||
|
||||
var clipSpace = Vector4(
|
||||
ndc.x * intersectionInClipSpace.w,
|
||||
ndcY * intersectionInClipSpace.w,
|
||||
ndc.z * intersectionInClipSpace.w,
|
||||
intersectionInClipSpace.w);
|
||||
Vector4 cameraSpace = inverseProjectionMatrix * clipSpace;
|
||||
Vector4 worldSpace = modelMatrix * cameraSpace;
|
||||
|
||||
var worldSpace3 = worldSpace.xyz.normalized() * currentPosition.length;
|
||||
currentPosition = worldSpace3;
|
||||
|
||||
// Zoom
|
||||
if (_queuedZoomDelta != 0.0) {
|
||||
var distToIntersection =
|
||||
(currentPosition - intersection).length - minimumDistance;
|
||||
|
||||
// if we somehow overshot the minimum distance, reset the camera to the minimum distance
|
||||
if (distToIntersection < 0) {
|
||||
currentPosition +=
|
||||
(intersection.normalized().scaled(-distToIntersection * 10));
|
||||
} else {
|
||||
bool zoomingOut = _queuedZoomDelta > 0;
|
||||
late Vector3 offset;
|
||||
|
||||
// when zooming, we don't always use fractions of the distance from
|
||||
// the camera to the target (this is due to float precision issues at
|
||||
// large distances, and also it doesn't work well for UI).
|
||||
|
||||
// if we're zooming out and the distance is less than 10m, we zoom out by 1 unit
|
||||
if (zoomingOut) {
|
||||
if (distToIntersection < 10) {
|
||||
offset = intersection.normalized();
|
||||
} else {
|
||||
offset = intersection.normalized().scaled(distToIntersection / 10);
|
||||
}
|
||||
// if we're zooming in and the distance is less than 5m, zoom in by 1/2 the distance,
|
||||
// otherwise 1/10 of the distance each time
|
||||
} else {
|
||||
if (distToIntersection < 5) {
|
||||
offset = intersection.normalized().scaled(-distToIntersection / 2);
|
||||
} else {
|
||||
offset = intersection.normalized().scaled(-distToIntersection / 10);
|
||||
}
|
||||
|
||||
if (offset.length > distToIntersection) {
|
||||
offset = Vector3.zero();
|
||||
}
|
||||
}
|
||||
currentPosition += offset;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate view matrix
|
||||
forward = -currentPosition.normalized();
|
||||
right = _up.cross(forward).normalized();
|
||||
up = forward.cross(right);
|
||||
|
||||
Matrix4 newViewMatrix = makeViewMatrix(currentPosition, Vector3.zero(), up);
|
||||
newViewMatrix.invert();
|
||||
|
||||
// Set the camera model matrix
|
||||
var camera = await _camera;
|
||||
await camera.setModelMatrix(newViewMatrix);
|
||||
|
||||
// Reset queued deltas
|
||||
_queuedRotationDelta = Vector2.zero();
|
||||
_queuedZoomDelta = 0.0;
|
||||
|
||||
_executing = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
import 'dart:async';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import '../../../viewer/viewer.dart';
|
||||
import '../delegates.dart';
|
||||
import '../input_handler.dart';
|
||||
|
||||
class FreeFlightInputHandlerDelegate implements InputHandlerDelegate {
|
||||
final ThermionViewer viewer;
|
||||
late Future<ThermionEntity> entity;
|
||||
final Vector3? minBounds;
|
||||
final Vector3? maxBounds;
|
||||
final double rotationSensitivity;
|
||||
final double movementSensitivity;
|
||||
final double zoomSensitivity;
|
||||
final double panSensitivity;
|
||||
final double? clampY;
|
||||
|
||||
static final _up = Vector3(0, 1, 0);
|
||||
static final _forward = Vector3(0, 0, -1);
|
||||
static final Vector3 _right = Vector3(1, 0, 0);
|
||||
|
||||
Vector2 _queuedRotationDelta = Vector2.zero();
|
||||
Vector3 _queuedTranslateDelta = Vector3.zero();
|
||||
double _queuedZoomDelta = 0.0;
|
||||
Vector3 _queuedMoveDelta = Vector3.zero();
|
||||
|
||||
FreeFlightInputHandlerDelegate(this.viewer,
|
||||
{this.minBounds,
|
||||
this.maxBounds,
|
||||
this.rotationSensitivity = 0.001,
|
||||
this.movementSensitivity = 0.1,
|
||||
this.zoomSensitivity = 0.1,
|
||||
this.panSensitivity = 0.1,
|
||||
this.clampY,
|
||||
ThermionEntity? entity}) {
|
||||
if (entity != null) {
|
||||
this.entity = Future.value(entity);
|
||||
} else {
|
||||
this.entity = viewer.getMainCameraEntity();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> queue(InputAction action, Vector3? delta) async {
|
||||
if (delta == null) return;
|
||||
|
||||
switch (action) {
|
||||
case InputAction.ROTATE:
|
||||
_queuedRotationDelta += Vector2(delta.x, delta.y);
|
||||
break;
|
||||
case InputAction.TRANSLATE:
|
||||
_queuedTranslateDelta += delta;
|
||||
break;
|
||||
case InputAction.PICK:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
case InputAction.NONE:
|
||||
break;
|
||||
case InputAction.ZOOM:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool _executing = false;
|
||||
|
||||
@override
|
||||
Future<void> execute() async {
|
||||
if (_executing) {
|
||||
return;
|
||||
}
|
||||
|
||||
_executing = true;
|
||||
|
||||
if (_queuedRotationDelta.length2 == 0.0 &&
|
||||
_queuedTranslateDelta.length2 == 0.0 &&
|
||||
_queuedZoomDelta == 0.0 &&
|
||||
_queuedMoveDelta.length2 == 0.0) {
|
||||
_executing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
final activeCamera = await viewer.getActiveCamera();
|
||||
|
||||
Matrix4 currentTransform = await viewer.getLocalTransform(await entity);
|
||||
|
||||
Quaternion currentRotation =
|
||||
Quaternion.fromRotation(currentTransform.getRotation());
|
||||
|
||||
// Calculate relative transform
|
||||
Matrix4 relativeTransform = Matrix4.identity();
|
||||
Vector3 relativeTranslation = Vector3.zero();
|
||||
Quaternion relativeRotation = Quaternion.identity();
|
||||
|
||||
// Apply rotation
|
||||
if (_queuedRotationDelta.length2 > 0.0) {
|
||||
double deltaX = _queuedRotationDelta.x * rotationSensitivity;
|
||||
double deltaY = _queuedRotationDelta.y * rotationSensitivity;
|
||||
|
||||
Quaternion yawRotation = Quaternion.axisAngle(_up, -deltaX);
|
||||
Quaternion pitchRotation = Quaternion.axisAngle(_right, -deltaY);
|
||||
|
||||
relativeRotation = pitchRotation * yawRotation;
|
||||
_queuedRotationDelta = Vector2.zero();
|
||||
}
|
||||
|
||||
// Apply pan
|
||||
if (_queuedTranslateDelta.length2 > 0.0) {
|
||||
double deltaX = _queuedTranslateDelta.x * panSensitivity;
|
||||
double deltaY = _queuedTranslateDelta.y * panSensitivity;
|
||||
double deltaZ = -_queuedTranslateDelta.z * panSensitivity;
|
||||
|
||||
relativeTranslation += _right * deltaX + _up * deltaY + _forward * deltaZ;
|
||||
_queuedTranslateDelta = Vector3.zero();
|
||||
}
|
||||
|
||||
// Apply zoom
|
||||
if (_queuedZoomDelta != 0.0) {
|
||||
Vector3 forward = _forward.clone()..applyQuaternion(currentRotation);
|
||||
relativeTranslation += forward * -_queuedZoomDelta * zoomSensitivity;
|
||||
_queuedZoomDelta = 0.0;
|
||||
}
|
||||
|
||||
// Apply queued movement
|
||||
if (_queuedMoveDelta.length2 > 0.0) {
|
||||
Vector3 forward = _forward.clone()..applyQuaternion(currentRotation);
|
||||
Vector3 right = _right.clone()..applyQuaternion(currentRotation);
|
||||
Vector3 up = _up.clone()..applyQuaternion(currentRotation);
|
||||
|
||||
relativeTranslation += (right * _queuedMoveDelta.x +
|
||||
up * _queuedMoveDelta.y +
|
||||
forward * _queuedMoveDelta.z) *
|
||||
movementSensitivity;
|
||||
|
||||
_queuedMoveDelta = Vector3.zero();
|
||||
}
|
||||
|
||||
// If the managed entity is not the active camera, we need to apply the rotation from the current camera model matrix
|
||||
// to the entity's translation
|
||||
if (await entity != activeCamera.getEntity()) {
|
||||
Matrix4 modelMatrix = await activeCamera.getModelMatrix();
|
||||
relativeTranslation = modelMatrix.getRotation() * relativeTranslation;
|
||||
}
|
||||
|
||||
// Compose relative transform
|
||||
relativeTransform = Matrix4.compose(
|
||||
relativeTranslation, relativeRotation, Vector3(1, 1, 1));
|
||||
|
||||
// Apply relative transform to current transform
|
||||
Matrix4 newTransform = currentTransform * relativeTransform;
|
||||
|
||||
// Extract new position and constrain it
|
||||
Vector3 newPosition = newTransform.getTranslation();
|
||||
newPosition = _constrainPosition(newPosition);
|
||||
|
||||
// Recompose final transform with constrained position
|
||||
Matrix4 finalTransform = Matrix4.compose(newPosition,
|
||||
Quaternion.fromRotation(newTransform.getRotation()), Vector3(1, 1, 1));
|
||||
|
||||
// Update camera
|
||||
await viewer.setTransform(await entity, finalTransform);
|
||||
|
||||
_executing = false;
|
||||
}
|
||||
|
||||
Vector3 _constrainPosition(Vector3 position) {
|
||||
if (minBounds != null) {
|
||||
position.x = position.x.clamp(minBounds!.x, double.infinity);
|
||||
position.y = position.y.clamp(minBounds!.y, double.infinity);
|
||||
position.z = position.z.clamp(minBounds!.z, double.infinity);
|
||||
}
|
||||
if (maxBounds != null) {
|
||||
position.x = position.x.clamp(double.negativeInfinity, maxBounds!.x);
|
||||
position.y = position.y.clamp(double.negativeInfinity, maxBounds!.y);
|
||||
position.z = position.z.clamp(double.negativeInfinity, maxBounds!.z);
|
||||
}
|
||||
|
||||
if (clampY != null) {
|
||||
position.y = clampY!;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
// import 'dart:async';
|
||||
|
||||
// import 'package:flutter/gestures.dart';
|
||||
// import 'package:flutter/services.dart';
|
||||
// import 'package:logging/logging.dart';
|
||||
// import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||
// import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
// import 'dart:ui';
|
||||
// import 'package:thermion_dart/thermion_dart/input/input_handler.dart';
|
||||
|
||||
// // Renamed implementation
|
||||
// class PickingCameraGestureHandler implements InputHandler {
|
||||
// final ThermionViewer viewer;
|
||||
// final bool enableCamera;
|
||||
// final bool enablePicking;
|
||||
// final Logger _logger = Logger("PickingCameraGestureHandler");
|
||||
|
||||
// AbstractGizmo? _gizmo;
|
||||
// Timer? _scrollTimer;
|
||||
// ThermionEntity? _highlightedEntity;
|
||||
// StreamSubscription<FilamentPickResult>? _pickResultSubscription;
|
||||
|
||||
// bool _gizmoAttached = false;
|
||||
|
||||
// PickingCameraGestureHandler({
|
||||
// required this.viewer,
|
||||
// this.enableCamera = true,
|
||||
// this.enablePicking = true,
|
||||
// }) {
|
||||
// try {
|
||||
// _gizmo = viewer.gizmo;
|
||||
// } catch (err) {
|
||||
// _logger.warning(
|
||||
// "Failed to get gizmo. If you are running on WASM, this is expected");
|
||||
// }
|
||||
|
||||
// _pickResultSubscription = viewer.pickResult.listen(_onPickResult);
|
||||
|
||||
// // Add keyboard listener
|
||||
// RawKeyboard.instance.addListener(_handleKeyEvent);
|
||||
// }
|
||||
|
||||
// @override
|
||||
// ThermionGestureState get currentState => _currentState;
|
||||
|
||||
// void _handleKeyEvent(RawKeyEvent event) {
|
||||
// if (event is RawKeyDownEvent &&
|
||||
// event.logicalKey == LogicalKeyboardKey.escape) {
|
||||
// _resetToNullState();
|
||||
// }
|
||||
// }
|
||||
|
||||
// void _resetToNullState() async {
|
||||
// _currentState = ThermionGestureState.NULL;
|
||||
// if (_highlightedEntity != null) {
|
||||
// await viewer.removeStencilHighlight(_highlightedEntity!);
|
||||
// _highlightedEntity = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void _onPickResult(FilamentPickResult result) async {
|
||||
// var targetEntity = await viewer.getAncestor(result.entity) ?? result.entity;
|
||||
|
||||
// if (_highlightedEntity != targetEntity) {
|
||||
// if (_highlightedEntity != null) {
|
||||
// await viewer.removeStencilHighlight(_highlightedEntity!);
|
||||
// }
|
||||
|
||||
// _highlightedEntity = targetEntity;
|
||||
// if (_highlightedEntity != null) {
|
||||
// await viewer.setStencilHighlight(_highlightedEntity!);
|
||||
// _gizmo?.attach(_highlightedEntity!);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onPointerHover(Offset localPosition, Offset delta) async {
|
||||
// if (_gizmoAttached) {
|
||||
// _gizmo?.checkHover(localPosition.dx, localPosition.dy);
|
||||
// }
|
||||
|
||||
// if (_highlightedEntity != null) {
|
||||
// await viewer.queuePositionUpdateFromViewportCoords(
|
||||
// _highlightedEntity!,
|
||||
// localPosition.dx,
|
||||
// localPosition.dy,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onPointerScroll(Offset localPosition, double scrollDelta) async {
|
||||
// if (!enableCamera) {
|
||||
// return;
|
||||
// }
|
||||
// if (_currentState == ThermionGestureState.NULL ||
|
||||
// _currentState == ThermionGestureState.ZOOMING) {
|
||||
// await _zoom(localPosition, scrollDelta);
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onPointerDown(Offset localPosition, int buttons) async {
|
||||
// if (_highlightedEntity != null) {
|
||||
// _resetToNullState();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (enablePicking && buttons != kMiddleMouseButton) {
|
||||
// viewer.pick(localPosition.dx.toInt(), localPosition.dy.toInt());
|
||||
// }
|
||||
|
||||
// if (buttons == kMiddleMouseButton && enableCamera) {
|
||||
// await viewer.rotateStart(localPosition.dx, localPosition.dy);
|
||||
// _currentState = ThermionGestureState.ROTATING;
|
||||
// } else if (buttons == kPrimaryMouseButton && enableCamera) {
|
||||
// await viewer.panStart(localPosition.dx, localPosition.dy);
|
||||
// _currentState = ThermionGestureState.PANNING;
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onPointerMove(
|
||||
// Offset localPosition, Offset delta, int buttons) async {
|
||||
// if (_highlightedEntity != null) {
|
||||
// await _handleEntityHighlightedMove(localPosition);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// switch (_currentState) {
|
||||
// case ThermionGestureState.NULL:
|
||||
// break;
|
||||
|
||||
// case ThermionGestureState.ROTATING:
|
||||
// if (enableCamera) {
|
||||
// await viewer.rotateUpdate(localPosition.dx, localPosition.dy);
|
||||
// }
|
||||
// break;
|
||||
// case ThermionGestureState.PANNING:
|
||||
// if (enableCamera) {
|
||||
// await viewer.panUpdate(localPosition.dx, localPosition.dy);
|
||||
// }
|
||||
// break;
|
||||
// case ThermionGestureState.ZOOMING:
|
||||
// // ignore
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onPointerUp(int buttons) async {
|
||||
// switch (_currentState) {
|
||||
// case ThermionGestureState.ROTATING:
|
||||
// await viewer.rotateEnd();
|
||||
// _currentState = ThermionGestureState.NULL;
|
||||
// break;
|
||||
// case ThermionGestureState.PANNING:
|
||||
// await viewer.panEnd();
|
||||
// _currentState = ThermionGestureState.NULL;
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Future<void> _handleEntityHighlightedMove(Offset localPosition) async {
|
||||
// if (_highlightedEntity != null) {
|
||||
// await viewer.queuePositionUpdateFromViewportCoords(
|
||||
// _highlightedEntity!,
|
||||
// localPosition.dx,
|
||||
// localPosition.dy,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// Future<void> _zoom(Offset localPosition, double scrollDelta) async {
|
||||
// _scrollTimer?.cancel();
|
||||
// _currentState = ThermionGestureState.ZOOMING;
|
||||
// await viewer.zoomBegin();
|
||||
// await viewer.zoomUpdate(
|
||||
// localPosition.dx, localPosition.dy, scrollDelta > 0 ? 1 : -1);
|
||||
|
||||
// _scrollTimer = Timer(const Duration(milliseconds: 100), () async {
|
||||
// await viewer.zoomEnd();
|
||||
// _currentState = ThermionGestureState.NULL;
|
||||
// });
|
||||
// }
|
||||
|
||||
// @override
|
||||
// void dispose() {
|
||||
// _pickResultSubscription?.cancel();
|
||||
// if (_highlightedEntity != null) {
|
||||
// viewer.removeStencilHighlight(_highlightedEntity!);
|
||||
// }
|
||||
// RawKeyboard.instance.removeListener(_handleKeyEvent);
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<bool> get initialized => viewer.initialized;
|
||||
|
||||
// @override
|
||||
// InputAction getActionForType(InputType type) {
|
||||
// // TODO: implement getActionForType
|
||||
// throw UnimplementedError();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onScaleEnd() {
|
||||
// // TODO: implement onScaleEnd
|
||||
// throw UnimplementedError();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onScaleStart() {
|
||||
// // TODO: implement onScaleStart
|
||||
// throw UnimplementedError();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> onScaleUpdate() {
|
||||
// // TODO: implement onScaleUpdate
|
||||
// throw UnimplementedError();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// void setActionForType(InputType type, InputAction action) {
|
||||
// // TODO: implement setActionForType
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,122 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import '../../../viewer/viewer.dart';
|
||||
import '../delegates.dart';
|
||||
import '../input_handler.dart';
|
||||
|
||||
class OverTheShoulderCameraDelegate implements InputHandlerDelegate {
|
||||
final ThermionViewer viewer;
|
||||
|
||||
late ThermionEntity player;
|
||||
late Camera camera;
|
||||
|
||||
final double rotationSensitivity;
|
||||
final double movementSensitivity;
|
||||
final double zoomSensitivity;
|
||||
final double panSensitivity;
|
||||
final double? clampY;
|
||||
|
||||
static final _up = Vector3(0, 1, 0);
|
||||
static final _forward = Vector3(0, 0, -1);
|
||||
static final Vector3 _right = Vector3(1, 0, 0);
|
||||
|
||||
Vector2 _queuedRotationDelta = Vector2.zero();
|
||||
double _queuedZoomDelta = 0.0;
|
||||
Vector3 _queuedMoveDelta = Vector3.zero();
|
||||
|
||||
final cameraPosition = Vector3(-0.5, 2.5, -3);
|
||||
final cameraUp = Vector3(0, 1, 0);
|
||||
var cameraLookAt = Vector3(0, 0.5, 3);
|
||||
|
||||
final void Function(Matrix4 transform)? onUpdate;
|
||||
|
||||
OverTheShoulderCameraDelegate(this.viewer, this.player, this.camera,
|
||||
{this.rotationSensitivity = 0.001,
|
||||
this.movementSensitivity = 0.1,
|
||||
this.zoomSensitivity = 0.1,
|
||||
this.panSensitivity = 0.1,
|
||||
this.clampY,
|
||||
ThermionEntity? entity,
|
||||
this.onUpdate}) {}
|
||||
|
||||
@override
|
||||
Future<void> queue(InputAction action, Vector3? delta) async {
|
||||
if (delta == null) return;
|
||||
|
||||
switch (action) {
|
||||
case InputAction.ROTATE:
|
||||
_queuedRotationDelta += Vector2(delta.x, delta.y);
|
||||
break;
|
||||
case InputAction.TRANSLATE:
|
||||
_queuedMoveDelta += delta;
|
||||
break;
|
||||
case InputAction.PICK:
|
||||
_queuedZoomDelta += delta.z;
|
||||
break;
|
||||
case InputAction.NONE:
|
||||
break;
|
||||
case InputAction.ZOOM:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool _executing = false;
|
||||
static bool get executing => _executing;
|
||||
|
||||
@override
|
||||
Future<void> execute() async {
|
||||
if (_executing) {
|
||||
return;
|
||||
}
|
||||
|
||||
_executing = true;
|
||||
|
||||
if (_queuedRotationDelta.length2 == 0.0 &&
|
||||
_queuedZoomDelta == 0.0 &&
|
||||
_queuedMoveDelta.length2 == 0.0) {
|
||||
_executing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4 currentPlayerTransform = await viewer.getWorldTransform(player);
|
||||
|
||||
// first we need to convert the move vector to player space
|
||||
var newTransform =
|
||||
Matrix4.translation(_queuedMoveDelta * movementSensitivity);
|
||||
|
||||
_queuedMoveDelta = Vector3.zero();
|
||||
Matrix4 newPlayerTransform = newTransform * currentPlayerTransform;
|
||||
await viewer.setTransform(player, newPlayerTransform);
|
||||
|
||||
if (_queuedZoomDelta != 0.0) {
|
||||
// Ignore zoom
|
||||
}
|
||||
|
||||
var inverted = newPlayerTransform.clone()..invert();
|
||||
|
||||
// camera is always looking at -Z, whereas models generally face towards +Z
|
||||
if (_queuedRotationDelta.length2 > 0.0) {
|
||||
double deltaX =
|
||||
_queuedRotationDelta.x * rotationSensitivity;
|
||||
double deltaY =
|
||||
_queuedRotationDelta.y * rotationSensitivity;
|
||||
|
||||
cameraLookAt = Matrix4.rotationY(-deltaX) *
|
||||
Matrix4.rotationX(-deltaY) *
|
||||
cameraLookAt;
|
||||
_queuedRotationDelta = Vector2.zero();
|
||||
}
|
||||
|
||||
var newCameraViewMatrix =
|
||||
makeViewMatrix(cameraPosition, cameraLookAt, cameraUp);
|
||||
newCameraViewMatrix.invert();
|
||||
var newCameraTransform = newPlayerTransform * newCameraViewMatrix;
|
||||
await camera.setTransform(newCameraTransform);
|
||||
|
||||
await viewer.queueTransformUpdates(
|
||||
[camera.getEntity(), player], [newCameraTransform, newPlayerTransform]);
|
||||
onUpdate?.call(newPlayerTransform);
|
||||
_executing = false;
|
||||
}
|
||||
}
|
||||
49
thermion_dart/lib/src/input/src/input_handler.dart
Normal file
49
thermion_dart/lib/src/input/src/input_handler.dart
Normal file
@@ -0,0 +1,49 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
enum InputType {
|
||||
LMB_DOWN,
|
||||
LMB_HOLD_AND_MOVE,
|
||||
LMB_UP,
|
||||
LMB_HOVER,
|
||||
MMB_DOWN,
|
||||
MMB_HOLD_AND_MOVE,
|
||||
|
||||
MMB_UP,
|
||||
MMB_HOVER,
|
||||
SCALE1,
|
||||
SCALE2,
|
||||
SCROLLWHEEL,
|
||||
POINTER_MOVE,
|
||||
KEYDOWN_W,
|
||||
KEYDOWN_A,
|
||||
KEYDOWN_S,
|
||||
KEYDOWN_D,
|
||||
}
|
||||
|
||||
enum PhysicalKey { W, A, S, D }
|
||||
|
||||
enum InputAction { TRANSLATE, ROTATE, PICK, ZOOM, NONE }
|
||||
|
||||
abstract class InputHandler {
|
||||
Stream get cameraUpdated;
|
||||
|
||||
Future<void> onPointerHover(Vector2 localPosition, Vector2 delta);
|
||||
Future<void> onPointerScroll(Vector2 localPosition, double scrollDelta);
|
||||
Future<void> onPointerDown(Vector2 localPosition, bool isMiddle);
|
||||
Future<void> onPointerMove(
|
||||
Vector2 localPosition, Vector2 delta, bool isMiddle);
|
||||
Future<void> onPointerUp(bool isMiddle);
|
||||
Future<void> onScaleStart(Vector2 focalPoint, int pointerCount);
|
||||
Future<void> onScaleUpdate(Vector2 focalPoint, Vector2 focalPointDelta, double horizontalScale, double verticalScale, double scale, int pointerCount);
|
||||
Future<void> onScaleEnd(int pointerCount);
|
||||
Future<bool> get initialized;
|
||||
Future dispose();
|
||||
|
||||
void setActionForType(InputType gestureType, InputAction gestureAction);
|
||||
InputAction? getActionForType(InputType gestureType);
|
||||
|
||||
void keyDown(PhysicalKey key);
|
||||
void keyUp(PhysicalKey key);
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../thermion_dart.dart';
|
||||
|
||||
class SceneV2 {
|
||||
final Map<String, AssetInfo> assets;
|
||||
final List<LightInfo> lights;
|
||||
44
thermion_dart/lib/src/utils/src/axis.dart
Normal file
44
thermion_dart/lib/src/utils/src/axis.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../viewer/viewer.dart';
|
||||
|
||||
class Axis {
|
||||
final ThermionViewer _viewer;
|
||||
final ThermionEntity xAxis;
|
||||
final ThermionEntity yAxis;
|
||||
final ThermionEntity zAxis;
|
||||
|
||||
Axis._(this.xAxis, this.yAxis, this.zAxis, this._viewer);
|
||||
|
||||
static Future<Axis> create(ThermionViewer viewer) async {
|
||||
final xAxis = await viewer!.createGeometry(
|
||||
Geometry(Float32List.fromList([0, 0, 0, 10, 0, 0]), [0, 1],
|
||||
primitiveType: PrimitiveType.LINES),
|
||||
materialInstance: await viewer!.createUnlitMaterialInstance());
|
||||
final yAxis = await viewer!.createGeometry(
|
||||
Geometry(Float32List.fromList([0, 0, 0, 0, 10, 0]), [0, 1],
|
||||
primitiveType: PrimitiveType.LINES),
|
||||
materialInstance: await viewer!.createUnlitMaterialInstance());
|
||||
final zAxis = await viewer!.createGeometry(
|
||||
Geometry(Float32List.fromList([0, 0, 0, 0, 0, 10]), [0, 1],
|
||||
primitiveType: PrimitiveType.LINES),
|
||||
materialInstance: await viewer!.createUnlitMaterialInstance());
|
||||
|
||||
await viewer!.setMaterialPropertyFloat4(
|
||||
xAxis, "baseColorFactor", 0, 1.0, 0.0, 0.0, 1.0);
|
||||
await viewer!.setMaterialPropertyFloat4(
|
||||
yAxis, "baseColorFactor", 0, 0.0, 1.0, 0.0, 1.0);
|
||||
await viewer!.setMaterialPropertyFloat4(
|
||||
zAxis, "baseColorFactor", 0, 0.0, 0.0, 1.0, 1.0);
|
||||
return Axis._(xAxis, yAxis, zAxis, viewer);
|
||||
}
|
||||
|
||||
Future setTransform(Matrix4 transform) async {
|
||||
await _viewer.setTransform(xAxis, transform);
|
||||
await _viewer.setTransform(yAxis, transform);
|
||||
await _viewer.setTransform(zAxis, transform);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@ import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
import '../../viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
class DartResourceLoader {
|
||||
static final _assets = <int, Pointer>{};
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/geometry.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/thermion_viewer_base.dart';
|
||||
|
||||
import '../../../thermion_dart.dart';
|
||||
|
||||
class GeometryHelper {
|
||||
static Geometry sphere({bool normals = true, bool uvs = true}) {
|
||||
@@ -1,18 +1,31 @@
|
||||
import 'dart:async';
|
||||
import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import '../thermion_viewer.dart';
|
||||
|
||||
class Gizmo extends AbstractGizmo {
|
||||
import 'package:thermion_dart/src/viewer/viewer.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
abstract class Gizmo {
|
||||
bool get isVisible;
|
||||
bool get isHovered;
|
||||
|
||||
void reset();
|
||||
|
||||
Future attach(ThermionEntity entity);
|
||||
Future detach();
|
||||
|
||||
Stream<Aabb2> get boundingBox;
|
||||
|
||||
void checkHover(int x, int y);
|
||||
}
|
||||
|
||||
abstract class BaseGizmo extends Gizmo {
|
||||
final ThermionEntity x;
|
||||
final ThermionEntity y;
|
||||
final ThermionEntity z;
|
||||
final ThermionEntity center;
|
||||
|
||||
final ThermionViewer _viewer;
|
||||
|
||||
ThermionEntity? _activeAxis;
|
||||
ThermionEntity? _activeEntity;
|
||||
ThermionViewer viewer;
|
||||
|
||||
bool _visible = false;
|
||||
bool get isVisible => _visible;
|
||||
@@ -25,10 +38,9 @@ class Gizmo extends AbstractGizmo {
|
||||
Stream<Aabb2> get boundingBox => _boundingBoxController.stream;
|
||||
final _boundingBoxController = StreamController<Aabb2>.broadcast();
|
||||
|
||||
Gizmo(this.x, this.y, this.z, this.center, this._viewer,
|
||||
{this.ignore = const <ThermionEntity>{}}) {
|
||||
_viewer.gizmoPickResult.listen(_onGizmoPickResult);
|
||||
_viewer.pickResult.listen(_onPickResult);
|
||||
BaseGizmo({required this.x, required this.y, required this.z, required this.center, required this.viewer,
|
||||
this.ignore = const <ThermionEntity>{}}) {
|
||||
onPick(_onGizmoPickResult);
|
||||
}
|
||||
|
||||
final _stopwatch = Stopwatch();
|
||||
@@ -51,12 +63,10 @@ class Gizmo extends AbstractGizmo {
|
||||
final axis = Vector3(_activeAxis == x ? 1.0 : 0.0,
|
||||
_activeAxis == y ? 1.0 : 0.0, _activeAxis == z ? 1.0 : 0.0);
|
||||
|
||||
await _viewer.queueRelativePositionUpdateWorldAxis(
|
||||
await viewer.queueRelativePositionUpdateWorldAxis(
|
||||
_activeEntity!,
|
||||
_transX * _viewer.pixelRatio,
|
||||
-_transY *
|
||||
_viewer
|
||||
.pixelRatio, // flip the sign because "up" in NDC Y axis is positive, but negative in Flutter
|
||||
_transX,
|
||||
-_transY, // flip the sign because "up" in NDC Y axis is positive, but negative in Flutter
|
||||
axis.x,
|
||||
axis.y,
|
||||
axis.z);
|
||||
@@ -69,10 +79,6 @@ class Gizmo extends AbstractGizmo {
|
||||
_activeAxis = null;
|
||||
}
|
||||
|
||||
void _onPickResult(FilamentPickResult result) async {
|
||||
await attach(result.entity);
|
||||
}
|
||||
|
||||
void _onGizmoPickResult(FilamentPickResult result) async {
|
||||
if (result.entity == x || result.entity == y || result.entity == z) {
|
||||
_activeAxis = result.entity;
|
||||
@@ -97,21 +103,25 @@ class Gizmo extends AbstractGizmo {
|
||||
_visible = true;
|
||||
|
||||
if (_activeEntity != null) {
|
||||
await _viewer.removeStencilHighlight(_activeEntity!);
|
||||
await viewer.removeStencilHighlight(_activeEntity!);
|
||||
}
|
||||
_activeEntity = entity;
|
||||
await _viewer.setGizmoVisibility(true);
|
||||
await _viewer.setParent(center, entity, preserveScaling: false);
|
||||
_boundingBoxController.sink.add(await _viewer.getViewportBoundingBox(x));
|
||||
|
||||
await viewer.setParent(center, entity, preserveScaling: false);
|
||||
_boundingBoxController.sink.add(await viewer.getViewportBoundingBox(x));
|
||||
}
|
||||
|
||||
Future detach() async {
|
||||
await _viewer.setGizmoVisibility(false);
|
||||
await setVisibility(false);
|
||||
}
|
||||
|
||||
@override
|
||||
void checkHover(double x, double y) {
|
||||
_viewer.pickGizmo(x.toInt(), y.toInt());
|
||||
void checkHover(int x, int y) {
|
||||
pick(x, y);
|
||||
}
|
||||
|
||||
Future pick(int x, int y);
|
||||
|
||||
Future setVisibility(bool visible);
|
||||
void onPick(void Function(PickResult result) callback);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Helper function to convert double4x4 to Matrix4
|
||||
import 'package:thermion_dart/thermion_dart/viewer/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:ffi';
|
||||
|
||||
4
thermion_dart/lib/src/utils/utils.dart
Normal file
4
thermion_dart/lib/src/utils/utils.dart
Normal file
@@ -0,0 +1,4 @@
|
||||
library;
|
||||
|
||||
export 'src/geometry.dart';
|
||||
export 'src/axis.dart';
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/entities.dart';
|
||||
import 'shared_types/shared_types.dart';
|
||||
|
||||
///
|
||||
@@ -26,7 +26,7 @@ Future<void> withVoidCallback(
|
||||
nativeCallable.close();
|
||||
}
|
||||
|
||||
Future<int> withPointerCallback<T extends NativeType>(
|
||||
Future<Pointer<T>> withPointerCallback<T extends NativeType>(
|
||||
Function(Pointer<NativeFunction<Void Function(Pointer<T>)>>)
|
||||
func) async {
|
||||
final completer = Completer<Pointer<T>>();
|
||||
@@ -39,7 +39,7 @@ Future<int> withPointerCallback<T extends NativeType>(
|
||||
func.call(nativeCallable.nativeFunction);
|
||||
var ptr = await completer.future;
|
||||
nativeCallable.close();
|
||||
return ptr.address;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Future<bool> withBoolCallback(
|
||||
91
thermion_dart/lib/src/viewer/src/ffi/src/ffi_camera.dart
Normal file
91
thermion_dart/lib/src/viewer/src/ffi/src/ffi_camera.dart
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../../../utils/src/matrix.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
import 'thermion_dart.g.dart' as g;
|
||||
|
||||
class FFICamera extends Camera {
|
||||
final Pointer<g.TCamera> camera;
|
||||
final Pointer<g.TEngine> engine;
|
||||
late ThermionEntity _entity;
|
||||
|
||||
FFICamera(this.camera, this.engine) {
|
||||
_entity = g.Camera_getEntity(camera);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far) async {
|
||||
g.Camera_setCustomProjectionWithCulling(
|
||||
camera, matrix4ToDouble4x4(projectionMatrix), near, far);
|
||||
}
|
||||
|
||||
Future<Matrix4> getModelMatrix() async {
|
||||
return double4x4ToMatrix4(g.Camera_getModelMatrix(camera));
|
||||
}
|
||||
|
||||
@override
|
||||
Future setTransform(Matrix4 transform) async {
|
||||
var entity = g.Camera_getEntity(camera);
|
||||
g.Engine_setTransform(engine, entity, matrix4ToDouble4x4(transform));
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLensProjection(
|
||||
{double near = kNear,
|
||||
double far = kFar,
|
||||
double aspect = 1.0,
|
||||
double focalLength = kFocalLength}) async {
|
||||
g.Camera_setLensProjection(camera, near, far, aspect, focalLength);
|
||||
}
|
||||
|
||||
@override
|
||||
ThermionEntity getEntity() {
|
||||
return _entity;
|
||||
}
|
||||
|
||||
@override
|
||||
Future setModelMatrix(Matrix4 matrix) async {
|
||||
g.Camera_setModelMatrix(camera, matrix4ToDouble4x4(matrix));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is FFICamera &&
|
||||
runtimeType == other.runtimeType &&
|
||||
camera == other.camera;
|
||||
|
||||
@override
|
||||
int get hashCode => camera.hashCode;
|
||||
|
||||
@override
|
||||
Future<double> getCullingFar() async {
|
||||
return g.Camera_getCullingFar(camera);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getNear() async {
|
||||
return g.Camera_getNear(camera);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getFocalLength() async {
|
||||
return g.Camera_getFocalLength(camera);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getViewMatrix() async {
|
||||
return double4x4ToMatrix4(g.Camera_getViewMatrix(camera));
|
||||
}
|
||||
|
||||
@override
|
||||
Future setProjection(Projection projection, double left, double right,
|
||||
double bottom, double top, double near, double far) async {
|
||||
var pType = g.Projection.values[projection.index];
|
||||
g.Camera_setProjection(camera, pType, left,
|
||||
right, bottom, top, near, far);
|
||||
}
|
||||
}
|
||||
50
thermion_dart/lib/src/viewer/src/ffi/src/ffi_gizmo.dart
Normal file
50
thermion_dart/lib/src/viewer/src/ffi/src/ffi_gizmo.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
import '../../../../utils/src/gizmo.dart';
|
||||
import '../../../viewer.dart';
|
||||
|
||||
class FFIGizmo extends BaseGizmo {
|
||||
Pointer<TGizmo> pointer;
|
||||
|
||||
late NativeCallable<GizmoPickCallbackFunction> _nativeCallback;
|
||||
FFIGizmo(
|
||||
this.pointer, ThermionViewer viewer) : super(x: 0, y: 0, z: 0, center: 0, viewer: viewer) {
|
||||
_nativeCallback =
|
||||
NativeCallable<GizmoPickCallbackFunction>.listener(_onPickResult);
|
||||
}
|
||||
|
||||
///
|
||||
/// The result(s) of calling [pickGizmo] (see below).
|
||||
///
|
||||
// Stream<PickResult> get onPick => _pickResultController.stream;
|
||||
// final _pickResultController = StreamController<PickResult>.broadcast();
|
||||
|
||||
void Function(PickResult)? _callback;
|
||||
|
||||
void onPick(void Function(PickResult) callback) {
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
void _onPickResult(DartEntityId entityId, int x, int y, Pointer<TView> view) {
|
||||
_callback?.call((entity: entityId, x: x, y: y));
|
||||
}
|
||||
|
||||
///
|
||||
/// Used to test whether a Gizmo is at the given viewport coordinates.
|
||||
/// Called by `FilamentGestureDetector` on a mouse/finger down event. You probably don't want to call this yourself.
|
||||
/// This is asynchronous and will require 2-3 frames to complete - subscribe to the [gizmoPickResult] stream to receive the results of this method.
|
||||
/// [x] and [y] must be in local logical coordinates (i.e. where 0,0 is at top-left of the ThermionWidget).
|
||||
///
|
||||
@override
|
||||
Future pick(int x, int y) async {
|
||||
Gizmo_pick(pointer, x.toInt(), y, _nativeCallback.nativeFunction);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setVisibility(bool visible) async {
|
||||
Gizmo_setVisibility(pointer, visible);
|
||||
}
|
||||
}
|
||||
69
thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart
Normal file
69
thermion_dart/lib/src/viewer/src/ffi/src/ffi_view.dart
Normal file
@@ -0,0 +1,69 @@
|
||||
import 'dart:ffi';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
|
||||
import 'ffi_camera.dart';
|
||||
import 'thermion_viewer_ffi.dart';
|
||||
|
||||
class FFIView extends View {
|
||||
final Pointer<TView> view;
|
||||
final Pointer<TViewer> viewer;
|
||||
|
||||
FFIView(this.view, this.viewer);
|
||||
|
||||
@override
|
||||
Future updateViewport(int width, int height) async {
|
||||
View_updateViewport(view, width, height);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRenderTarget(covariant FFIRenderTarget renderTarget) async {
|
||||
View_setRenderTarget(view, renderTarget.renderTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setCamera(FFICamera camera) async {
|
||||
View_setCamera(view, camera.camera);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Viewport> getViewport() async {
|
||||
TViewport vp = View_getViewport(view);
|
||||
return Viewport(vp.left, vp.bottom, vp.width, vp.height);
|
||||
}
|
||||
|
||||
@override
|
||||
Camera getCamera() {
|
||||
final engine = Viewer_getEngine(viewer);
|
||||
return FFICamera(View_getCamera(view), engine);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa) async {
|
||||
View_setAntiAliasing(view, msaa, fxaa, taa);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setPostProcessing(bool enabled) async {
|
||||
View_setPostProcessing(view, enabled);
|
||||
}
|
||||
|
||||
Future setRenderable(bool renderable, FFISwapChain swapChain) async {
|
||||
Viewer_setViewRenderable(viewer, swapChain.swapChain, view, renderable);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setFrustumCullingEnabled(bool enabled) async {
|
||||
View_setFrustumCullingEnabled(view, enabled);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBloom(double strength) async {
|
||||
View_setBloom(view, strength);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setToneMapper(ToneMapper mapper) async {
|
||||
final engine = await Viewer_getEngine(viewer);
|
||||
View_setToneMappingRenderThread(view, engine, mapper.index);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,3 @@
|
||||
library;
|
||||
|
||||
export 'src/thermion_viewer_ffi.dart' show ThermionViewerFFI;
|
||||
export 'src/camera_ffi.dart';
|
||||
30
thermion_dart/lib/src/viewer/src/shared_types/camera.dart
Normal file
30
thermion_dart/lib/src/viewer/src/shared_types/camera.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../thermion_viewer_base.dart';
|
||||
|
||||
enum Projection { Perspective, Orthographic }
|
||||
|
||||
abstract class Camera {
|
||||
Future setProjection(Projection projection, double left, double right,
|
||||
double bottom, double top, double near, double far);
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far);
|
||||
|
||||
Future setLensProjection(
|
||||
{double near = kNear,
|
||||
double far = kFar,
|
||||
double aspect = 1.0,
|
||||
double focalLength = kFocalLength});
|
||||
|
||||
Future<Matrix4> getViewMatrix();
|
||||
Future<Matrix4> getModelMatrix();
|
||||
Future setModelMatrix(Matrix4 matrix);
|
||||
|
||||
ThermionEntity getEntity();
|
||||
|
||||
Future setTransform(Matrix4 transform);
|
||||
|
||||
Future<double> getNear();
|
||||
Future<double> getCullingFar();
|
||||
Future<double> getFocalLength();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/thermion_dart/viewer/thermion_viewer_base.dart';
|
||||
import '../../viewer.dart';
|
||||
|
||||
class Geometry {
|
||||
final Float32List vertices;
|
||||
@@ -1,4 +1,4 @@
|
||||
// see filament Manipulator.h for more details
|
||||
@Deprecated(
|
||||
"This is used the native pointer manipulator Prefer ThermionGestureHandler instead")
|
||||
"This is used the native pointer manipulator Prefer InputHandler instead")
|
||||
enum ManipulatorMode { ORBIT, MAP, FREE_FLIGHT }
|
||||
@@ -1,6 +1,7 @@
|
||||
abstract class MaterialInstance {
|
||||
Future setDepthWriteEnabled(bool enabled);
|
||||
Future setDepthCullingEnabled(bool enabled);
|
||||
Future setParameterFloat2(String name, double x, double y);
|
||||
}
|
||||
|
||||
enum AlphaMode { OPAQUE, MASK, BLEND }
|
||||
@@ -0,0 +1,5 @@
|
||||
// "picking" means clicking/tapping on the viewport, and unprojecting the X/Y coordinate to determine whether any renderable entities were present at those coordinates.
|
||||
import '../../viewer.dart';
|
||||
|
||||
typedef FilamentPickResult = ({ThermionEntity entity, int x, int y});
|
||||
typedef PickResult = FilamentPickResult;
|
||||
@@ -0,0 +1,3 @@
|
||||
abstract class RenderTarget {
|
||||
Future destroy();
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
library shared_types;
|
||||
|
||||
export 'swap_chain.dart';
|
||||
export 'view.dart';
|
||||
export 'render_target.dart';
|
||||
export 'camera.dart';
|
||||
export 'material.dart';
|
||||
export 'texture.dart';
|
||||
export 'entities.dart';
|
||||
@@ -0,0 +1,3 @@
|
||||
abstract class SwapChain {
|
||||
Future destroy();
|
||||
}
|
||||
30
thermion_dart/lib/src/viewer/src/shared_types/view.dart
Normal file
30
thermion_dart/lib/src/viewer/src/shared_types/view.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'swap_chain.dart';
|
||||
|
||||
///
|
||||
/// The viewport currently attached to a [View].
|
||||
///
|
||||
/// The dimensions here are guaranteed to be in physical pixels.
|
||||
///
|
||||
class Viewport {
|
||||
final int left;
|
||||
final int bottom;
|
||||
final int width;
|
||||
final int height;
|
||||
|
||||
Viewport(this.left, this.bottom, this.width, this.height);
|
||||
}
|
||||
|
||||
abstract class View {
|
||||
Future<Viewport> getViewport();
|
||||
Future updateViewport(int width, int height);
|
||||
Future setRenderTarget(covariant RenderTarget? renderTarget);
|
||||
Future setCamera(covariant Camera camera);
|
||||
Camera getCamera();
|
||||
Future setPostProcessing(bool enabled);
|
||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa);
|
||||
Future setRenderable(bool renderable, covariant SwapChain swapChain);
|
||||
Future setFrustumCullingEnabled(bool enabled);
|
||||
Future setToneMapper(ToneMapper mapper);
|
||||
Future setBloom(double strength);
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import 'package:thermion_dart/thermion_dart/viewer/events.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/camera.dart';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/events.dart';
|
||||
import '../../utils/src/gizmo.dart';
|
||||
import 'shared_types/shared_types.dart';
|
||||
export 'shared_types/shared_types.dart';
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:async';
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
|
||||
import 'shared_types/view.dart';
|
||||
|
||||
const double kNear = 0.05;
|
||||
const double kFar = 1000.0;
|
||||
const double kFocalLength = 28.0;
|
||||
@@ -21,16 +21,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future<bool> get initialized;
|
||||
|
||||
///
|
||||
/// The current dimensions of the viewport (in physical pixels).
|
||||
///
|
||||
var viewportDimensions = (0.0, 0.0);
|
||||
|
||||
///
|
||||
/// The current ratio of logical to physical pixels.
|
||||
///
|
||||
late double pixelRatio;
|
||||
|
||||
///
|
||||
/// The result(s) of calling [pick] (see below).
|
||||
/// This may be a broadcast stream, so you should ensure you have subscribed to this stream before calling [pick].
|
||||
@@ -38,11 +28,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Stream<FilamentPickResult> get pickResult;
|
||||
|
||||
///
|
||||
/// The result(s) of calling [pickGizmo] (see below).
|
||||
///
|
||||
Stream<FilamentPickResult> get gizmoPickResult;
|
||||
|
||||
///
|
||||
/// A Stream containing entities added/removed to/from to the scene.
|
||||
///
|
||||
@@ -61,17 +46,51 @@ abstract class ThermionViewer {
|
||||
///
|
||||
/// Render a single frame immediately.
|
||||
///
|
||||
Future render();
|
||||
Future render({covariant SwapChain? swapChain});
|
||||
|
||||
///
|
||||
/// Requests a single frame to be rendered. This is only intended to be used internally.
|
||||
///
|
||||
void requestFrame();
|
||||
Future requestFrame();
|
||||
|
||||
///
|
||||
/// Render a single frame and copy the pixel buffer to [out].
|
||||
///
|
||||
Future<Uint8List> capture();
|
||||
Future<Uint8List> capture(
|
||||
{covariant SwapChain? swapChain,
|
||||
covariant View? view,
|
||||
covariant RenderTarget? renderTarget});
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<SwapChain> createHeadlessSwapChain(int width, int height);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<SwapChain> createSwapChain(int handle);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<RenderTarget> createRenderTarget(
|
||||
int width, int height, int textureHandle);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setRenderTarget(covariant RenderTarget renderTarget);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<View> createView();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<View> getViewAt(int index);
|
||||
|
||||
///
|
||||
/// Sets the framerate for continuous rendering when [setRendering] is enabled.
|
||||
@@ -197,12 +216,16 @@ abstract class ThermionViewer {
|
||||
/// Specify [numInstances] to create multiple instances (this is more efficient than dynamically instantating at a later time). You can then retrieve the created instances with [getInstances].
|
||||
/// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData].
|
||||
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
|
||||
/// If [loadResourcesAsync] is true, resources (textures, materials, etc) will
|
||||
/// be loaded asynchronously (so expect some material/texture pop-in);
|
||||
///
|
||||
///
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data,
|
||||
{int numInstances = 1,
|
||||
bool keepData = false,
|
||||
int priority = 4,
|
||||
int layer = 0});
|
||||
int layer = 0,
|
||||
bool loadResourcesAsync});
|
||||
|
||||
///
|
||||
/// Create a new instance of [entity].
|
||||
@@ -229,36 +252,6 @@ abstract class ThermionViewer {
|
||||
Future<ThermionEntity> loadGltf(String path, String relativeResourcePath,
|
||||
{bool keepData = false});
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panStart(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panUpdate(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panEnd();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateStart(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateUpdate(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateEnd();
|
||||
|
||||
///
|
||||
/// Set the weights for all morph targets in [entity] to [weights].
|
||||
/// Note that [weights] must contain values for ALL morph targets, but no exception will be thrown if you don't do so (you'll just get incorrect results).
|
||||
@@ -365,6 +358,13 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future setTransform(ThermionEntity entity, Matrix4 transform);
|
||||
|
||||
///
|
||||
/// Sets multiple transforms (relative to parent) simultaneously for [entity].
|
||||
/// Uses mutex to ensure that transform updates aren't split across frames.
|
||||
///
|
||||
Future queueTransformUpdates(
|
||||
List<ThermionEntity> entities, List<Matrix4> transforms);
|
||||
|
||||
///
|
||||
/// Updates the bone matrices for [entity] (which must be the ThermionEntity
|
||||
/// returned by [loadGlb/loadGltf]).
|
||||
@@ -394,21 +394,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future clearEntities();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomBegin();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomUpdate(double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomEnd();
|
||||
|
||||
///
|
||||
/// Schedules the glTF animation at [index] in [entity] to start playing on the next frame.
|
||||
///
|
||||
@@ -501,15 +486,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future<double> getCameraCullingFar();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setCameraLensProjection(
|
||||
{double near = kNear,
|
||||
double far = kFar,
|
||||
double? aspect,
|
||||
double focalLength = kFocalLength});
|
||||
|
||||
///
|
||||
/// Sets the focus distance for the camera.
|
||||
///
|
||||
@@ -648,14 +624,6 @@ abstract class ThermionViewer {
|
||||
Future setRotation(
|
||||
ThermionEntity entity, double rads, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Queues an update to the worldspace position for [entity] to {x,y,z}.
|
||||
/// The actual update will occur on the next frame, and will be subject to collision detection.
|
||||
///
|
||||
Future queuePositionUpdate(
|
||||
ThermionEntity entity, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// TODO
|
||||
///
|
||||
@@ -668,20 +636,6 @@ abstract class ThermionViewer {
|
||||
Future queueRelativePositionUpdateWorldAxis(ThermionEntity entity,
|
||||
double viewportX, double viewportY, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Queues an update to the worldspace rotation for [entity].
|
||||
/// The actual update will occur on the next frame, and will be subject to collision detection.
|
||||
///
|
||||
Future queueRotationUpdate(
|
||||
ThermionEntity entity, double rads, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Same as [queueRotationUpdate].
|
||||
///
|
||||
Future queueRotationUpdateQuat(ThermionEntity entity, Quaternion quat,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Enable/disable postprocessing (disabled by default).
|
||||
///
|
||||
@@ -731,30 +685,11 @@ abstract class ThermionViewer {
|
||||
///
|
||||
void pick(int x, int y);
|
||||
|
||||
///
|
||||
/// Used to test whether a Gizmo is at the given viewport coordinates.
|
||||
/// Called by `FilamentGestureDetector` on a mouse/finger down event. You probably don't want to call this yourself.
|
||||
/// This is asynchronous and will require 2-3 frames to complete - subscribe to the [gizmoPickResult] stream to receive the results of this method.
|
||||
/// [x] and [y] must be in local logical coordinates (i.e. where 0,0 is at top-left of the ThermionWidget).
|
||||
///
|
||||
void pickGizmo(int x, int y);
|
||||
|
||||
///
|
||||
/// Retrieves the name assigned to the given ThermionEntity (usually corresponds to the glTF mesh name).
|
||||
///
|
||||
String? getNameForEntity(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the options for manipulating the camera via the viewport.
|
||||
/// ManipulatorMode.FREE_FLIGHT and ManipulatorMode.MAP are currently unsupported and will throw an exception.
|
||||
///
|
||||
@Deprecated("Use ThermionGestureHandler instead")
|
||||
Future setCameraManipulatorOptions(
|
||||
{ManipulatorMode mode = ManipulatorMode.ORBIT,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01});
|
||||
|
||||
///
|
||||
/// Returns all child entities under [parent].
|
||||
///
|
||||
@@ -774,17 +709,6 @@ abstract class ThermionViewer {
|
||||
Future<List<String>> getChildEntityNames(ThermionEntity entity,
|
||||
{bool renderableOnly = true});
|
||||
|
||||
///
|
||||
/// If [recording] is set to true, each frame the framebuffer/texture will be written to /tmp/output_*.png.
|
||||
/// This will impact performance; handle with care.
|
||||
///
|
||||
Future setRecording(bool recording);
|
||||
|
||||
///
|
||||
/// Sets the output directory where recorded PNGs will be placed.
|
||||
///
|
||||
Future setRecordingOutputDirectory(String outputDirectory);
|
||||
|
||||
///
|
||||
/// An [entity] will only be animatable after an animation component is attached.
|
||||
/// Any calls to [playAnimation]/[setBoneAnimation]/[setMorphAnimation] will have no visual effect until [addAnimationComponent] has been called on the instance.
|
||||
@@ -845,9 +769,9 @@ abstract class ThermionViewer {
|
||||
Future setPriority(ThermionEntity entityId, int priority);
|
||||
|
||||
///
|
||||
/// The gizmo for translating/rotating objects. Only one gizmo is present in the scene.
|
||||
/// The gizmo for translating/rotating objects. Only one gizmo can be active for a given view.
|
||||
///
|
||||
AbstractGizmo? get gizmo;
|
||||
Future<Gizmo> createGizmo(covariant View view);
|
||||
|
||||
///
|
||||
/// Register a callback to be invoked when this viewer is disposed.
|
||||
@@ -871,11 +795,6 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future setVisibilityLayer(ThermionEntity entity, int layer);
|
||||
|
||||
///
|
||||
/// Show/hide the translation gizmo.
|
||||
///
|
||||
Future setGizmoVisibility(bool visible);
|
||||
|
||||
///
|
||||
/// Renders an outline around [entity] with the given color.
|
||||
///
|
||||
@@ -960,4 +879,40 @@ abstract class ThermionViewer {
|
||||
///
|
||||
Future<MaterialInstance?> getMaterialInstanceAt(
|
||||
ThermionEntity entity, int index);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Camera> createCamera();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setActiveCamera(covariant Camera camera);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Camera> getActiveCamera();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future registerRequestFrameHook(Future Function() hook);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future unregisterRequestFrameHook(Future Function() hook);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
int getCameraCount();
|
||||
|
||||
///
|
||||
/// Returns the camera specified by the given index. Note that the camera at
|
||||
/// index 0 is always the main camera; this cannot be destroyed.
|
||||
///
|
||||
Camera getCameraAt(int index);
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/events.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/camera.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/thermion_viewer_base.dart';
|
||||
import 'package:thermion_dart/src/utils/src/gizmo.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/swap_chain.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/shared_types/view.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:async';
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'events.dart';
|
||||
import 'shared_types/camera.dart';
|
||||
|
||||
class ThermionViewerStub extends ThermionViewer {
|
||||
@override
|
||||
@@ -240,10 +241,6 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement gizmo
|
||||
AbstractGizmo? get gizmo => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future hide(ThermionEntity entity, String? meshName) {
|
||||
// TODO: implement hide
|
||||
@@ -384,11 +381,6 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future render() {
|
||||
// TODO: implement render
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement rendering
|
||||
@@ -723,12 +715,6 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> capture() {
|
||||
// TODO: implement capture
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Aabb2> getBoundingBox(ThermionEntity entity) {
|
||||
// TODO: implement getBoundingBox
|
||||
@@ -907,11 +893,7 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0}) {
|
||||
// TODO: implement loadGlbFromBuffer
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future setMaterialPropertyInt(ThermionEntity entity, String propertyName, int materialIndex, int value) {
|
||||
@@ -944,8 +926,8 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
}
|
||||
|
||||
@override
|
||||
void requestFrame() {
|
||||
// TODO: implement requestFrame
|
||||
Future requestFrame() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -966,5 +948,120 @@ class ThermionViewerStub extends ThermionViewer {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Camera> createCamera() {
|
||||
// TODO: implement createCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future registerRenderHook(Future Function() hook) {
|
||||
// TODO: implement registerRenderHook
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setActiveCamera(covariant Camera camera) {
|
||||
// TODO: implement setActiveCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future registerRequestFrameHook(Future Function() hook) {
|
||||
// TODO: implement registerRequestFrameHook
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future unregisterRequestFrameHook(Future Function() hook) {
|
||||
// TODO: implement unregisterRequestFrameHook
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Camera getCameraAt(int index) {
|
||||
// TODO: implement getCameraAt
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
int getCameraCount() {
|
||||
// TODO: implement getCameraCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future queueTransformUpdates(List<ThermionEntity> entities, List<Matrix4> transforms) {
|
||||
// TODO: implement queueTransformUpdates
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<RenderTarget> createRenderTarget(int width, int height, int textureHandle) {
|
||||
// TODO: implement createRenderTarget
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRenderTarget(covariant RenderTarget renderTarget) {
|
||||
// TODO: implement setRenderTarget
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<View> createView() {
|
||||
// TODO: implement createView
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<View> getViewAt(int index) {
|
||||
// TODO: implement getViewAt
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<Gizmo> createGizmo(covariant View view) {
|
||||
// TODO: implement createGizmo
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SwapChain> createHeadlessSwapChain(int width, int height) {
|
||||
// TODO: implement createHeadlessSwapChain
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> capture({covariant SwapChain? swapChain, covariant View? view, covariant RenderTarget? renderTarget}) {
|
||||
// TODO: implement capture
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SwapChain> createSwapChain(handle) {
|
||||
// TODO: implement createSwapChain
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future render({covariant SwapChain? swapChain}) {
|
||||
// TODO: implement render
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Camera> getActiveCamera() {
|
||||
// TODO: implement getActiveCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data, {int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync= false}) {
|
||||
// TODO: implement loadGlbFromBuffer
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,759 @@
|
||||
// @JS()
|
||||
// library thermion_flutter_js;
|
||||
|
||||
// import 'dart:js_interop';
|
||||
// import 'package:logging/logging.dart';
|
||||
// import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
// import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
// import 'dart:js_interop_unsafe';
|
||||
// import 'package:vector_math/vector_math_64.dart';
|
||||
// import '../../../viewer.dart';
|
||||
// import 'thermion_viewer_js_shim.dart';
|
||||
|
||||
// ///
|
||||
// /// A (Dart) class that wraps a (Dart) instance of [ThermionViewer],
|
||||
// /// but exported to JS by binding to a global property.
|
||||
// /// This is effectively an implementation of [ThermionViewerJSShim];
|
||||
// /// allowing users to interact with an instance of [ThermionViewer]
|
||||
// /// (presumably compiled to WASM) from any Javascript context (including
|
||||
// /// the browser console).
|
||||
// ///
|
||||
// @JSExport()
|
||||
// class ThermionViewerJSDartBridge {
|
||||
// final _logger = Logger("ThermionViewerJSDartBridge");
|
||||
// final ThermionViewer viewer;
|
||||
|
||||
// ThermionViewerJSDartBridge(this.viewer);
|
||||
|
||||
// void bind({String globalPropertyName = "thermionViewer"}) {
|
||||
// var wrapper = createJSInteropWrapper<ThermionViewerJSDartBridge>(this)
|
||||
// as ThermionViewerJSShim;
|
||||
// globalContext.setProperty(globalPropertyName.toJS, wrapper);
|
||||
// }
|
||||
|
||||
// JSPromise<JSBoolean> get initialized {
|
||||
// return viewer.initialized.then((v) => v.toJS).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSBoolean get rendering => viewer.rendering.toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setRendering(bool render) {
|
||||
// return viewer.setRendering(render).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise render() => viewer.render().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSUint8Array> capture() {
|
||||
// return viewer.capture().then((captured) => captured.toJS).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setFrameRate(int framerate) => viewer.setFrameRate(framerate).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise dispose() => viewer.dispose().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setBackgroundImage(String path, {bool fillHeight = false}) =>
|
||||
// viewer.setBackgroundImage(path, fillHeight: fillHeight).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setBackgroundImagePosition(double x, double y,
|
||||
// {bool clamp = false}) =>
|
||||
// viewer.setBackgroundImagePosition(x, y, clamp: clamp).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise clearBackgroundImage() => viewer.clearBackgroundImage().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setBackgroundColor(double r, double g, double b, double alpha) =>
|
||||
// viewer.setBackgroundColor(r, g, b, alpha).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise loadSkybox(String skyboxPath) => viewer.loadSkybox(skyboxPath).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise removeSkybox() => viewer.removeSkybox().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise loadIbl(String lightingPath, double intensity) {
|
||||
// _logger.info("Loading IBL from $lightingPath with intensity $intensity");
|
||||
// return viewer.loadIbl(lightingPath, intensity: intensity).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise rotateIbl(JSArray<JSNumber> rotation) {
|
||||
// var matrix =
|
||||
// Matrix3.fromList(rotation.toDart.map((v) => v.toDartDouble).toList());
|
||||
// return viewer.rotateIbl(matrix).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise removeIbl() => viewer.removeIbl().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> addLight(
|
||||
// int type,
|
||||
// double colour,
|
||||
// double intensity,
|
||||
// double posX,
|
||||
// double posY,
|
||||
// double posZ,
|
||||
// double dirX,
|
||||
// double dirY,
|
||||
// double dirZ,
|
||||
// double falloffRadius,
|
||||
// double spotLightConeInner,
|
||||
// double spotLightConeOuter,
|
||||
// double sunAngularRadius,
|
||||
// double sunHaloSize,
|
||||
// double sunHaloFallof,
|
||||
// bool castShadows) {
|
||||
// return viewer
|
||||
// .addLight(LightType.values[type], colour, intensity, posX, posY, posZ,
|
||||
// dirX, dirY, dirZ,
|
||||
// falloffRadius: falloffRadius,
|
||||
// spotLightConeInner: spotLightConeInner,
|
||||
// spotLightConeOuter: spotLightConeOuter,
|
||||
// sunAngularRadius: sunAngularRadius,
|
||||
// sunHaloSize: sunHaloSize,
|
||||
// sunHaloFallof: sunHaloFallof,
|
||||
// castShadows: castShadows)
|
||||
// .then((entity) => entity.toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise removeLight(ThermionEntity light) => viewer.removeLight(light).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise clearLights() => viewer.clearLights().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
|
||||
// _logger.info("Loading GLB from path $path with numInstances $numInstances");
|
||||
// return viewer
|
||||
// .loadGlb(path, numInstances: numInstances)
|
||||
// .then((entity) => entity.toJS)
|
||||
// .catchError((err) {
|
||||
// _logger.info("Error: $err");
|
||||
// }).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> createInstance(ThermionEntity entity) {
|
||||
// return viewer.createInstance(entity).then((instance) => instance.toJS).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getInstanceCount(ThermionEntity entity) =>
|
||||
// viewer.getInstanceCount(entity).then((v) => v.toJS).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getInstances(ThermionEntity entity) {
|
||||
// return viewer
|
||||
// .getInstances(entity)
|
||||
// .then((instances) =>
|
||||
// instances.map((instance) => instance.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> loadGltf(String path, String relativeResourcePath,
|
||||
// {bool keepData = false}) {
|
||||
// return viewer
|
||||
// .loadGltf(path, relativeResourcePath, keepData: keepData)
|
||||
// .then((entity) => entity.toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise panStart(double x, double y) => viewer.panStart(x, y).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise panUpdate(double x, double y) => viewer.panUpdate(x, y).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise panEnd() => viewer.panEnd().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise rotateStart(double x, double y) => viewer.rotateStart(x, y).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise rotateUpdate(double x, double y) => viewer.rotateUpdate(x, y).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise rotateEnd() => viewer.rotateEnd().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setMorphTargetWeights(
|
||||
// ThermionEntity entity, JSArray<JSNumber> weights) {
|
||||
// var dartWeights = weights.toDart.map((w) => w.toDartDouble).toList();
|
||||
// return viewer.setMorphTargetWeights(entity, dartWeights).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSString>> getMorphTargetNames(
|
||||
// ThermionEntity entity, ThermionEntity childEntity) {
|
||||
// var morphTargetNames = viewer
|
||||
// .getMorphTargetNames(entity, childEntity)
|
||||
// .then((v) => v.map((s) => s.toJS).toList().toJS);
|
||||
// return morphTargetNames.toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSString>> getBoneNames(
|
||||
// ThermionEntity entity, int skinIndex) {
|
||||
// return viewer
|
||||
// .getBoneNames(entity, skinIndex: skinIndex)
|
||||
// .then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSString>> getAnimationNames(ThermionEntity entity) =>
|
||||
// viewer
|
||||
// .getAnimationNames(entity)
|
||||
// .then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getAnimationDuration(
|
||||
// ThermionEntity entity, int animationIndex) =>
|
||||
// viewer
|
||||
// .getAnimationDuration(entity, animationIndex)
|
||||
// .then((v) => v.toJS)
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// void clearMorphAnimationData(ThermionEntity entity) {
|
||||
// viewer.clearMorphAnimationData(entity);
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setMorphAnimationData(
|
||||
// ThermionEntity entity,
|
||||
// JSArray<JSArray<JSNumber>> animation,
|
||||
// JSArray<JSString> morphTargets,
|
||||
// JSArray<JSString>? targetMeshNames,
|
||||
// double frameLengthInMs) {
|
||||
// try {
|
||||
// var morphTargetsDart = morphTargets.toDart.map((m) => m.toDart).toList();
|
||||
// var animationDataDart = animation.toDart
|
||||
// .map((x) => x.toDart.map((y) => y.toDartDouble).toList())
|
||||
// .toList();
|
||||
|
||||
// var morphAnimationData = MorphAnimationData(
|
||||
// animationDataDart, morphTargetsDart,
|
||||
// frameLengthInMs: frameLengthInMs);
|
||||
// var targetMeshNamesDart =
|
||||
// targetMeshNames?.toDart.map((x) => x.toDart).toList();
|
||||
// if (animationDataDart.first.length != morphTargetsDart.length) {
|
||||
// throw Exception(
|
||||
// "Length mismatch between morph targets and animation data");
|
||||
// }
|
||||
// var result = viewer
|
||||
// .setMorphAnimationData(
|
||||
// entity,
|
||||
// morphAnimationData,
|
||||
// targetMeshNames: targetMeshNamesDart,
|
||||
// )
|
||||
// .onError((err, st) {
|
||||
// _logger.severe("ERROR SETTING MORPH ANIMATION DATA : $err\n$st");
|
||||
// return null;
|
||||
// });
|
||||
// return result.toJS;
|
||||
// } catch (err, st) {
|
||||
// _logger.severe(err);
|
||||
// _logger.severe(st);
|
||||
// rethrow;
|
||||
// }
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise resetBones(ThermionEntity entity) => viewer.resetBones(entity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise addBoneAnimation(
|
||||
// ThermionEntity entity,
|
||||
// JSArray<JSString> bones,
|
||||
// JSArray<JSArray<JSArray<JSNumber>>> frameData,
|
||||
// JSNumber frameLengthInMs,
|
||||
// JSNumber spaceEnum,
|
||||
// JSNumber skinIndex,
|
||||
// JSNumber fadeInInSecs,
|
||||
// JSNumber fadeOutInSecs,
|
||||
// JSNumber maxDelta) {
|
||||
// var frameDataDart = frameData.toDart
|
||||
// .map((frame) => frame.toDart
|
||||
// .map((v) {
|
||||
// var values = v.toDart;
|
||||
// var trans = v64.Vector3(values[0].toDartDouble,
|
||||
// values[1].toDartDouble, values[2].toDartDouble);
|
||||
// var rot = v64.Quaternion(
|
||||
// values[3].toDartDouble,
|
||||
// values[4].toDartDouble,
|
||||
// values[5].toDartDouble,
|
||||
// values[6].toDartDouble);
|
||||
// return (rotation: rot, translation: trans);
|
||||
// })
|
||||
// .cast<BoneAnimationFrame>()
|
||||
// .toList())
|
||||
// .toList();
|
||||
|
||||
// var data = BoneAnimationData(
|
||||
// bones.toDart.map((n) => n.toDart).toList(), frameDataDart,
|
||||
// frameLengthInMs: frameLengthInMs.toDartDouble,
|
||||
// space: Space.values[spaceEnum.toDartInt]);
|
||||
|
||||
// return viewer
|
||||
// .addBoneAnimation(entity, data,
|
||||
// skinIndex: skinIndex.toDartInt,
|
||||
// fadeInInSecs: fadeInInSecs.toDartDouble,
|
||||
// fadeOutInSecs: fadeOutInSecs.toDartDouble)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise removeEntity(ThermionEntity entity) =>
|
||||
// viewer.removeEntity(entity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise clearEntities() {
|
||||
// return viewer.clearEntities().toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise zoomBegin() => viewer.zoomBegin().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise zoomUpdate(double x, double y, double z) =>
|
||||
// viewer.zoomUpdate(x, y, z).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise zoomEnd() => viewer.zoomEnd().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise playAnimation(ThermionEntity entity, int index,
|
||||
// {bool loop = false,
|
||||
// bool reverse = false,
|
||||
// bool replaceActive = true,
|
||||
// double crossfade = 0.0,
|
||||
// double startOffset = 0.0}) =>
|
||||
// viewer
|
||||
// .playAnimation(entity, index,
|
||||
// loop: loop,
|
||||
// reverse: reverse,
|
||||
// replaceActive: replaceActive,
|
||||
// crossfade: crossfade,
|
||||
// startOffset: startOffset)
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise playAnimationByName(ThermionEntity entity, String name,
|
||||
// {bool loop = false,
|
||||
// bool reverse = false,
|
||||
// bool replaceActive = true,
|
||||
// double crossfade = 0.0}) =>
|
||||
// viewer
|
||||
// .playAnimationByName(
|
||||
// entity,
|
||||
// name,
|
||||
// loop: loop,
|
||||
// reverse: reverse,
|
||||
// replaceActive: replaceActive,
|
||||
// crossfade: crossfade,
|
||||
// )
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setAnimationFrame(
|
||||
// ThermionEntity entity, int index, int animationFrame) =>
|
||||
// viewer
|
||||
// .setAnimationFrame(
|
||||
// entity,
|
||||
// index,
|
||||
// animationFrame,
|
||||
// )
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise stopAnimation(ThermionEntity entity, int animationIndex) =>
|
||||
// viewer.stopAnimation(entity, animationIndex).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise stopAnimationByName(ThermionEntity entity, String name) =>
|
||||
// viewer.stopAnimationByName(entity, name).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCamera(ThermionEntity entity, String? name) =>
|
||||
// viewer.setCamera(entity, name).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setMainCamera() => viewer.setMainCamera().toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getMainCamera() {
|
||||
// throw UnimplementedError("TODO");
|
||||
// // return viewer.getMainCamera().then((camera) => camera.toJS).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setParent(
|
||||
// ThermionEntity child, ThermionEntity parent, bool preserveScaling) {
|
||||
// return viewer
|
||||
// .setParent(child, parent, preserveScaling: preserveScaling)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraFov(double degrees, bool horizontal) =>
|
||||
// viewer.setCameraFov(degrees, horizontal: horizontal).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setToneMapping(int mapper) =>
|
||||
// viewer.setToneMapping(ToneMapper.values[mapper]).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setBloom(double bloom) => viewer.setBloom(bloom).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraFocalLength(double focalLength) =>
|
||||
// viewer.setCameraFocalLength(focalLength).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraCulling(double near, double far) =>
|
||||
// viewer.setCameraCulling(near, far).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getCameraCullingNear() =>
|
||||
// viewer.getCameraCullingNear().then((v) => v.toJS).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getCameraCullingFar() =>
|
||||
// viewer.getCameraCullingFar().then((v) => v.toJS).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraFocusDistance(double focusDistance) =>
|
||||
// viewer.setCameraFocusDistance(focusDistance).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getCameraPosition() {
|
||||
// throw UnimplementedError();
|
||||
// // return viewer.getCameraPosition().then((position) => position.toJS).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getCameraModelMatrix() {
|
||||
// throw UnimplementedError();
|
||||
// // return viewer.getCameraModelMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getCameraViewMatrix() {
|
||||
// throw UnimplementedError();
|
||||
// // return viewer.getCameraViewMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getCameraProjectionMatrix() {
|
||||
// throw UnimplementedError();
|
||||
// // return viewer.getCameraProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getCameraCullingProjectionMatrix() {
|
||||
// throw UnimplementedError();
|
||||
// // return viewer.getCameraCullingProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getCameraFrustum() {
|
||||
// throw UnimplementedError();
|
||||
// // return viewer.getCameraFrustum().then((frustum) => frustum.toJS).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraPosition(double x, double y, double z) =>
|
||||
// viewer.setCameraPosition(x, y, z).toJS;
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getCameraRotation() {
|
||||
// return viewer
|
||||
// .getCameraRotation()
|
||||
// .then((rotation) => rotation.storage.map((v) => v.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise moveCameraToAsset(ThermionEntity entity) =>
|
||||
// throw UnimplementedError();
|
||||
// // viewer.moveCameraToAsset(entity)).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setViewFrustumCulling(JSBoolean enabled) =>
|
||||
// throw UnimplementedError();
|
||||
// // viewer.setViewFrustumCulling(enabled).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraExposure(
|
||||
// double aperture, double shutterSpeed, double sensitivity) =>
|
||||
// viewer.setCameraExposure(aperture, shutterSpeed, sensitivity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraRotation(JSArray<JSNumber> quaternion) {
|
||||
// var dartVals = quaternion.toDart;
|
||||
// return viewer
|
||||
// .setCameraRotation(v64.Quaternion(
|
||||
// dartVals[0].toDartDouble,
|
||||
// dartVals[1].toDartDouble,
|
||||
// dartVals[2].toDartDouble,
|
||||
// dartVals[3].toDartDouble))
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraModelMatrix(JSArray<JSNumber> matrix) {
|
||||
// throw UnimplementedError();
|
||||
// // viewer.setCameraModelMatrix(matrix).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setMaterialColor(ThermionEntity entity, String meshName,
|
||||
// int materialIndex, double r, double g, double b, double a) =>
|
||||
// throw UnimplementedError();
|
||||
// // viewer.setMaterialColor(
|
||||
// // entity),
|
||||
// // meshName,
|
||||
// // materialIndex,
|
||||
// // r,
|
||||
// // g,
|
||||
// // b,
|
||||
// // a,
|
||||
// // ).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise transformToUnitCube(ThermionEntity entity) =>
|
||||
// viewer.transformToUnitCube(entity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setPosition(ThermionEntity entity, double x, double y, double z) =>
|
||||
// viewer.setPosition(entity, x, y, z).toJS;
|
||||
// @JSExport()
|
||||
// JSPromise setScale(ThermionEntity entity, double scale) =>
|
||||
// viewer.setScale(entity, scale).toJS;
|
||||
// @JSExport()
|
||||
// JSPromise setRotation(
|
||||
// ThermionEntity entity, double rads, double x, double y, double z) =>
|
||||
// viewer.setRotation(entity, rads, x, y, z).toJS;
|
||||
// @JSExport()
|
||||
// JSPromise queuePositionUpdate(
|
||||
// ThermionEntity entity, double x, double y, double z, bool relative) =>
|
||||
// viewer
|
||||
// .queuePositionUpdate(
|
||||
// entity,
|
||||
// x,
|
||||
// y,
|
||||
// z,
|
||||
// relative: relative,
|
||||
// )
|
||||
// .toJS;
|
||||
// @JSExport()
|
||||
// JSPromise queueRotationUpdate(ThermionEntity entity, double rads, double x,
|
||||
// double y, double z, bool relative) =>
|
||||
// viewer
|
||||
// .queueRotationUpdate(
|
||||
// entity,
|
||||
// rads,
|
||||
// x,
|
||||
// y,
|
||||
// z,
|
||||
// relative: relative,
|
||||
// )
|
||||
// .toJS;
|
||||
// @JSExport()
|
||||
// JSPromise queueRotationUpdateQuat(
|
||||
// ThermionEntity entity, JSArray<JSNumber> quat, JSBoolean relative) =>
|
||||
// throw UnimplementedError();
|
||||
// // viewer.queueRotationUpdateQuat(
|
||||
// // entity,
|
||||
// // quat.toDartQuaternion(),
|
||||
// // relative: relative,
|
||||
// // ).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setPostProcessing(bool enabled) =>
|
||||
// viewer.setPostProcessing(enabled).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setAntiAliasing(bool msaa, bool fxaa, bool taa) =>
|
||||
// viewer.setAntiAliasing(msaa, fxaa, taa).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setRotationQuat(
|
||||
// ThermionEntity entity, JSArray<JSNumber> rotation) =>
|
||||
// throw UnimplementedError();
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise reveal(ThermionEntity entity, String? meshName) =>
|
||||
// viewer.reveal(entity, meshName).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise hide(ThermionEntity entity, String? meshName) =>
|
||||
// viewer.hide(entity, meshName).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// void pick(int x, int y) => viewer.pick(x, y);
|
||||
|
||||
// @JSExport()
|
||||
// String? getNameForEntity(ThermionEntity entity) =>
|
||||
// viewer.getNameForEntity(entity);
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setCameraManipulatorOptions({
|
||||
// int mode = 0,
|
||||
// double orbitSpeedX = 0.01,
|
||||
// double orbitSpeedY = 0.01,
|
||||
// double zoomSpeed = 0.01,
|
||||
// }) =>
|
||||
// viewer
|
||||
// .setCameraManipulatorOptions(
|
||||
// mode: ManipulatorMode.values[mode],
|
||||
// orbitSpeedX: orbitSpeedX,
|
||||
// orbitSpeedY: orbitSpeedY,
|
||||
// zoomSpeed: zoomSpeed,
|
||||
// )
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getChildEntities(
|
||||
// ThermionEntity parent, bool renderableOnly) {
|
||||
// return viewer
|
||||
// .getChildEntities(
|
||||
// parent,
|
||||
// renderableOnly,
|
||||
// )
|
||||
// .then((entities) => entities.map((entity) => entity.toJS).toList().toJS)
|
||||
// .onError((e, st) async {
|
||||
// _logger.severe("Error : $e\n$st");
|
||||
// return <JSNumber>[].toJS;
|
||||
// }).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSNumber> getChildEntity(ThermionEntity parent, String childName) {
|
||||
// return viewer
|
||||
// .getChildEntity(
|
||||
// parent,
|
||||
// childName,
|
||||
// )
|
||||
// .then((entity) => entity.toJS)
|
||||
// .onError((e, st) async {
|
||||
// _logger.severe("Error getChildEntity : $e\n$st");
|
||||
// return 0.toJS;
|
||||
// }).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSString>> getChildEntityNames(
|
||||
// ThermionEntity entity, bool renderableOnly) =>
|
||||
// viewer
|
||||
// .getChildEntityNames(
|
||||
// entity,
|
||||
// renderableOnly: renderableOnly,
|
||||
// )
|
||||
// .then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setRecording(bool recording) => viewer.setRecording(recording).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setRecordingOutputDirectory(String outputDirectory) =>
|
||||
// viewer.setRecordingOutputDirectory(outputDirectory).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise addAnimationComponent(ThermionEntity entity) =>
|
||||
// viewer.addAnimationComponent(entity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise removeAnimationComponent(ThermionEntity entity) =>
|
||||
// viewer.removeAnimationComponent(entity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise getParent(ThermionEntity entity) =>
|
||||
// viewer.removeAnimationComponent(entity).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise getBone(ThermionEntity entity, int boneIndex, int skinIndex) =>
|
||||
// viewer.getBone(entity, boneIndex, skinIndex: skinIndex).toJS;
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getLocalTransform(ThermionEntity entity) {
|
||||
// return viewer
|
||||
// .getLocalTransform(entity)
|
||||
// .then((t) => t.storage.map((v) => v.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise<JSArray<JSNumber>> getWorldTransform(ThermionEntity entity) {
|
||||
// return viewer
|
||||
// .getWorldTransform(entity)
|
||||
// .then((t) => t.storage.map((v) => v.toJS).toList().toJS)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setTransform(ThermionEntity entity, JSArray<JSNumber> transform) {
|
||||
// return viewer
|
||||
// .setTransform(
|
||||
// entity,
|
||||
// Matrix4.fromList(
|
||||
// transform.toDart.map((v) => v.toDartDouble).toList()))
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise updateBoneMatrices(ThermionEntity entity) {
|
||||
// return viewer.updateBoneMatrices(entity).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setBoneTransform(ThermionEntity entity, int boneIndex,
|
||||
// JSArray<JSNumber> transform, int skinIndex) {
|
||||
// return viewer
|
||||
// .setBoneTransform(
|
||||
// entity,
|
||||
// boneIndex,
|
||||
// Matrix4.fromList(
|
||||
// transform.toDart.map((v) => v.toDartDouble).toList()),
|
||||
// skinIndex: skinIndex)
|
||||
// .toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise addCollisionComponent(ThermionEntity entity,
|
||||
// {JSFunction? callback, bool affectsTransform = false}) {
|
||||
// throw UnimplementedError();
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setShadowsEnabled(bool enabled) {
|
||||
// return viewer.setShadowsEnabled(enabled).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setShadowType(int shadowType) {
|
||||
// return viewer.setShadowType(ShadowType.values[shadowType]).toJS;
|
||||
// }
|
||||
|
||||
// @JSExport()
|
||||
// JSPromise setSoftShadowOptions(
|
||||
// double penumbraScale, double penumbraRatioScale) {
|
||||
// return viewer.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toJS;
|
||||
// }
|
||||
// }
|
||||
1107
thermion_dart/lib/src/viewer/src/web_js/src/thermion_viewer_js.dart
Normal file
1107
thermion_dart/lib/src/viewer/src/web_js/src/thermion_viewer_js.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ library thermion_flutter_js;
|
||||
|
||||
import 'dart:js_interop';
|
||||
|
||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
import '../../shared_types/shared_types.dart';
|
||||
|
||||
///
|
||||
/// An extension type on [JSObject] that represents a
|
||||
77
thermion_dart/lib/src/viewer/src/web_wasm/src/camera.dart
Normal file
77
thermion_dart/lib/src/viewer/src/web_wasm/src/camera.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../thermion_viewer_base.dart';
|
||||
|
||||
class ThermionWasmCamera extends Camera {
|
||||
|
||||
final int pointer;
|
||||
|
||||
ThermionWasmCamera(this.pointer);
|
||||
|
||||
@override
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far) {
|
||||
// TODO: implement setProjectionMatrixWithCulling
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getModelMatrix() {
|
||||
// TODO: implement getModelMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLensProjection({double near = kNear, double far = kFar, double aspect = 1.0, double focalLength = kFocalLength}) {
|
||||
// TODO: implement setLensProjection
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setTransform(Matrix4 transform) {
|
||||
// TODO: implement setTransform
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
ThermionEntity getEntity() {
|
||||
// TODO: implement getEntity
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setModelMatrix(Matrix4 matrix) {
|
||||
// TODO: implement setModelMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getCullingFar() {
|
||||
// TODO: implement getCullingFar
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getFocalLength() {
|
||||
// TODO: implement getFocalLength
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getNear() {
|
||||
// TODO: implement getNear
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getViewMatrix() {
|
||||
// TODO: implement getViewMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setProjection(Projection projection, double left, double right, double bottom, double top, double near, double far) {
|
||||
// TODO: implement setProjection
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/material.dart';
|
||||
import '../../../viewer.dart';
|
||||
|
||||
class ThermionWasmMaterialInstance extends MaterialInstance {
|
||||
final int pointer;
|
||||
@@ -15,4 +15,10 @@ class ThermionWasmMaterialInstance extends MaterialInstance {
|
||||
// TODO: implement setDepthWriteEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat2(String name, double x, double y) {
|
||||
// TODO: implement setParameterFloat2
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
7
thermion_dart/lib/src/viewer/viewer.dart
Normal file
7
thermion_dart/lib/src/viewer/viewer.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
library thermion_viewer;
|
||||
|
||||
export 'src/thermion_viewer_base.dart';
|
||||
export 'src/thermion_viewer_stub.dart'
|
||||
if (dart.library.io) 'src/ffi/thermion_viewer_ffi.dart'
|
||||
if (dart.library.js_interop) 'src/web_wasm/thermion_viewer_web_wasm.dart';
|
||||
export 'src/shared_types/shared_types.dart';
|
||||
@@ -1,5 +1,5 @@
|
||||
library filament_dart;
|
||||
|
||||
export 'thermion_dart/thermion_viewer.dart';
|
||||
export 'thermion_dart/entities/entity_transform_controller.dart';
|
||||
export 'thermion_dart/utils/geometry.dart';
|
||||
export 'src/viewer/viewer.dart';
|
||||
export 'src/input/input.dart';
|
||||
export 'src/utils/utils.dart';
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
abstract class AbstractGizmo {
|
||||
|
||||
bool get isVisible;
|
||||
bool get isHovered;
|
||||
|
||||
Future translate(double transX, double transY);
|
||||
|
||||
void reset();
|
||||
|
||||
Future attach(ThermionEntity entity);
|
||||
|
||||
Future detach();
|
||||
|
||||
Stream<Aabb2> get boundingBox;
|
||||
|
||||
void checkHover(double x, double y);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
library thermion_viewer;
|
||||
|
||||
export 'viewer/thermion_viewer_base.dart';
|
||||
export 'viewer/thermion_viewer_stub.dart'
|
||||
if (dart.library.io) 'viewer/ffi/thermion_viewer_ffi.dart'
|
||||
if (dart.library.js_interop) 'viewer/web/thermion_viewer_wasm.dart';
|
||||
@@ -1,22 +0,0 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:thermion_dart/thermion_dart/utils/matrix.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/camera.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
class ThermionFFICamera extends Camera {
|
||||
final Pointer<TCamera> pointer;
|
||||
|
||||
ThermionFFICamera(this.pointer);
|
||||
|
||||
@override
|
||||
Future setProjectionMatrixWithCulling(Matrix4 projectionMatrix,
|
||||
double near, double far) async {
|
||||
Camera_setCustomProjectionWithCulling(
|
||||
pointer,
|
||||
matrix4ToDouble4x4(projectionMatrix),
|
||||
near,
|
||||
far);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
abstract class Camera {
|
||||
|
||||
Future setProjectionMatrixWithCulling(Matrix4 projectionMatrix, double near, double far);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
// "picking" means clicking/tapping on the viewport, and unprojecting the X/Y coordinate to determine whether any renderable entities were present at those coordinates.
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/shared_types.dart';
|
||||
|
||||
typedef FilamentPickResult = ({ThermionEntity entity, double x, double y});
|
||||
typedef ThermionPickResult = FilamentPickResult;
|
||||
@@ -1,761 +0,0 @@
|
||||
@JS()
|
||||
library thermion_flutter_js;
|
||||
|
||||
import 'dart:js_interop';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:thermion_dart/thermion_dart/viewer/web_js/src/thermion_viewer_js_shim.dart';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||
import 'dart:js_interop_unsafe';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
///
|
||||
/// A (Dart) class that wraps a (Dart) instance of [ThermionViewer],
|
||||
/// but exported to JS by binding to a global property.
|
||||
/// This is effectively an implementation of [ThermionViewerJSShim];
|
||||
/// allowing users to interact with an instance of [ThermionViewer]
|
||||
/// (presumably compiled to WASM) from any Javascript context (including
|
||||
/// the browser console).
|
||||
///
|
||||
@JSExport()
|
||||
class ThermionViewerJSDartBridge {
|
||||
final _logger = Logger("ThermionViewerJSDartBridge");
|
||||
final ThermionViewer viewer;
|
||||
|
||||
ThermionViewerJSDartBridge(this.viewer);
|
||||
|
||||
void bind({String globalPropertyName = "thermionViewer"}) {
|
||||
var wrapper = createJSInteropWrapper<ThermionViewerJSDartBridge>(this)
|
||||
as ThermionViewerJSShim;
|
||||
globalContext.setProperty(globalPropertyName.toJS, wrapper);
|
||||
}
|
||||
|
||||
JSPromise<JSBoolean> get initialized {
|
||||
return viewer.initialized.then((v) => v.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSBoolean get rendering => viewer.rendering.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRendering(bool render) {
|
||||
return viewer.setRendering(render).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise render() => viewer.render().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSUint8Array> capture() {
|
||||
return viewer.capture().then((captured) => captured.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setFrameRate(int framerate) => viewer.setFrameRate(framerate).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise dispose() => viewer.dispose().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBackgroundImage(String path, {bool fillHeight = false}) =>
|
||||
viewer.setBackgroundImage(path, fillHeight: fillHeight).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBackgroundImagePosition(double x, double y,
|
||||
{bool clamp = false}) =>
|
||||
viewer.setBackgroundImagePosition(x, y, clamp: clamp).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise clearBackgroundImage() => viewer.clearBackgroundImage().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBackgroundColor(double r, double g, double b, double alpha) =>
|
||||
viewer.setBackgroundColor(r, g, b, alpha).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise loadSkybox(String skyboxPath) => viewer.loadSkybox(skyboxPath).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeSkybox() => viewer.removeSkybox().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise loadIbl(String lightingPath, double intensity) {
|
||||
_logger.info("Loading IBL from $lightingPath with intensity $intensity");
|
||||
return viewer.loadIbl(lightingPath, intensity: intensity).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateIbl(JSArray<JSNumber> rotation) {
|
||||
var matrix =
|
||||
Matrix3.fromList(rotation.toDart.map((v) => v.toDartDouble).toList());
|
||||
return viewer.rotateIbl(matrix).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeIbl() => viewer.removeIbl().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> addLight(
|
||||
int type,
|
||||
double colour,
|
||||
double intensity,
|
||||
double posX,
|
||||
double posY,
|
||||
double posZ,
|
||||
double dirX,
|
||||
double dirY,
|
||||
double dirZ,
|
||||
double falloffRadius,
|
||||
double spotLightConeInner,
|
||||
double spotLightConeOuter,
|
||||
double sunAngularRadius,
|
||||
double sunHaloSize,
|
||||
double sunHaloFallof,
|
||||
bool castShadows) {
|
||||
return viewer
|
||||
.addLight(LightType.values[type], colour, intensity, posX, posY, posZ,
|
||||
dirX, dirY, dirZ,
|
||||
falloffRadius: falloffRadius,
|
||||
spotLightConeInner: spotLightConeInner,
|
||||
spotLightConeOuter: spotLightConeOuter,
|
||||
sunAngularRadius: sunAngularRadius,
|
||||
sunHaloSize: sunHaloSize,
|
||||
sunHaloFallof: sunHaloFallof,
|
||||
castShadows: castShadows)
|
||||
.then((entity) => entity.toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeLight(ThermionEntity light) => viewer.removeLight(light).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise clearLights() => viewer.clearLights().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
|
||||
_logger.info("Loading GLB from path $path with numInstances $numInstances");
|
||||
return viewer
|
||||
.loadGlb(path, numInstances: numInstances)
|
||||
.then((entity) => entity.toJS)
|
||||
.catchError((err) {
|
||||
_logger.info("Error: $err");
|
||||
}).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> createInstance(ThermionEntity entity) {
|
||||
return viewer.createInstance(entity).then((instance) => instance.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getInstanceCount(ThermionEntity entity) =>
|
||||
viewer.getInstanceCount(entity).then((v) => v.toJS).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getInstances(ThermionEntity entity) {
|
||||
return viewer
|
||||
.getInstances(entity)
|
||||
.then((instances) =>
|
||||
instances.map((instance) => instance.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> loadGltf(String path, String relativeResourcePath,
|
||||
{bool keepData = false}) {
|
||||
return viewer
|
||||
.loadGltf(path, relativeResourcePath, keepData: keepData)
|
||||
.then((entity) => entity.toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise panStart(double x, double y) => viewer.panStart(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise panUpdate(double x, double y) => viewer.panUpdate(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise panEnd() => viewer.panEnd().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateStart(double x, double y) => viewer.rotateStart(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateUpdate(double x, double y) => viewer.rotateUpdate(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateEnd() => viewer.rotateEnd().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMorphTargetWeights(
|
||||
ThermionEntity entity, JSArray<JSNumber> weights) {
|
||||
var dartWeights = weights.toDart.map((w) => w.toDartDouble).toList();
|
||||
return viewer.setMorphTargetWeights(entity, dartWeights).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getMorphTargetNames(
|
||||
ThermionEntity entity, ThermionEntity childEntity) {
|
||||
var morphTargetNames = viewer
|
||||
.getMorphTargetNames(entity, childEntity)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS);
|
||||
return morphTargetNames.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getBoneNames(
|
||||
ThermionEntity entity, int skinIndex) {
|
||||
return viewer
|
||||
.getBoneNames(entity, skinIndex: skinIndex)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getAnimationNames(ThermionEntity entity) =>
|
||||
viewer
|
||||
.getAnimationNames(entity)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getAnimationDuration(
|
||||
ThermionEntity entity, int animationIndex) =>
|
||||
viewer
|
||||
.getAnimationDuration(entity, animationIndex)
|
||||
.then((v) => v.toJS)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
void clearMorphAnimationData(ThermionEntity entity) {
|
||||
viewer.clearMorphAnimationData(entity);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMorphAnimationData(
|
||||
ThermionEntity entity,
|
||||
JSArray<JSArray<JSNumber>> animation,
|
||||
JSArray<JSString> morphTargets,
|
||||
JSArray<JSString>? targetMeshNames,
|
||||
double frameLengthInMs) {
|
||||
try {
|
||||
var morphTargetsDart = morphTargets.toDart.map((m) => m.toDart).toList();
|
||||
var animationDataDart = animation.toDart
|
||||
.map((x) => x.toDart.map((y) => y.toDartDouble).toList())
|
||||
.toList();
|
||||
|
||||
var morphAnimationData = MorphAnimationData(
|
||||
animationDataDart, morphTargetsDart,
|
||||
frameLengthInMs: frameLengthInMs);
|
||||
var targetMeshNamesDart =
|
||||
targetMeshNames?.toDart.map((x) => x.toDart).toList();
|
||||
if (animationDataDart.first.length != morphTargetsDart.length) {
|
||||
throw Exception(
|
||||
"Length mismatch between morph targets and animation data");
|
||||
}
|
||||
var result = viewer
|
||||
.setMorphAnimationData(
|
||||
entity,
|
||||
morphAnimationData,
|
||||
targetMeshNames: targetMeshNamesDart,
|
||||
)
|
||||
.onError((err, st) {
|
||||
_logger.severe("ERROR SETTING MORPH ANIMATION DATA : $err\n$st");
|
||||
return null;
|
||||
});
|
||||
return result.toJS;
|
||||
} catch (err, st) {
|
||||
_logger.severe(err);
|
||||
_logger.severe(st);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise resetBones(ThermionEntity entity) => viewer.resetBones(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise addBoneAnimation(
|
||||
ThermionEntity entity,
|
||||
JSArray<JSString> bones,
|
||||
JSArray<JSArray<JSArray<JSNumber>>> frameData,
|
||||
JSNumber frameLengthInMs,
|
||||
JSNumber spaceEnum,
|
||||
JSNumber skinIndex,
|
||||
JSNumber fadeInInSecs,
|
||||
JSNumber fadeOutInSecs,
|
||||
JSNumber maxDelta) {
|
||||
var frameDataDart = frameData.toDart
|
||||
.map((frame) => frame.toDart
|
||||
.map((v) {
|
||||
var values = v.toDart;
|
||||
var trans = v64.Vector3(values[0].toDartDouble,
|
||||
values[1].toDartDouble, values[2].toDartDouble);
|
||||
var rot = v64.Quaternion(
|
||||
values[3].toDartDouble,
|
||||
values[4].toDartDouble,
|
||||
values[5].toDartDouble,
|
||||
values[6].toDartDouble);
|
||||
return (rotation: rot, translation: trans);
|
||||
})
|
||||
.cast<BoneAnimationFrame>()
|
||||
.toList())
|
||||
.toList();
|
||||
|
||||
var data = BoneAnimationData(
|
||||
bones.toDart.map((n) => n.toDart).toList(), frameDataDart,
|
||||
frameLengthInMs: frameLengthInMs.toDartDouble,
|
||||
space: Space.values[spaceEnum.toDartInt]);
|
||||
|
||||
return viewer
|
||||
.addBoneAnimation(entity, data,
|
||||
skinIndex: skinIndex.toDartInt,
|
||||
fadeInInSecs: fadeInInSecs.toDartDouble,
|
||||
fadeOutInSecs: fadeOutInSecs.toDartDouble)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeEntity(ThermionEntity entity) =>
|
||||
viewer.removeEntity(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise clearEntities() {
|
||||
return viewer.clearEntities().toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise zoomBegin() => viewer.zoomBegin().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise zoomUpdate(double x, double y, double z) =>
|
||||
viewer.zoomUpdate(x, y, z).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise zoomEnd() => viewer.zoomEnd().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise playAnimation(ThermionEntity entity, int index,
|
||||
{bool loop = false,
|
||||
bool reverse = false,
|
||||
bool replaceActive = true,
|
||||
double crossfade = 0.0,
|
||||
double startOffset = 0.0}) =>
|
||||
viewer
|
||||
.playAnimation(entity, index,
|
||||
loop: loop,
|
||||
reverse: reverse,
|
||||
replaceActive: replaceActive,
|
||||
crossfade: crossfade,
|
||||
startOffset: startOffset)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise playAnimationByName(ThermionEntity entity, String name,
|
||||
{bool loop = false,
|
||||
bool reverse = false,
|
||||
bool replaceActive = true,
|
||||
double crossfade = 0.0}) =>
|
||||
viewer
|
||||
.playAnimationByName(
|
||||
entity,
|
||||
name,
|
||||
loop: loop,
|
||||
reverse: reverse,
|
||||
replaceActive: replaceActive,
|
||||
crossfade: crossfade,
|
||||
)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setAnimationFrame(
|
||||
ThermionEntity entity, int index, int animationFrame) =>
|
||||
viewer
|
||||
.setAnimationFrame(
|
||||
entity,
|
||||
index,
|
||||
animationFrame,
|
||||
)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise stopAnimation(ThermionEntity entity, int animationIndex) =>
|
||||
viewer.stopAnimation(entity, animationIndex).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise stopAnimationByName(ThermionEntity entity, String name) =>
|
||||
viewer.stopAnimationByName(entity, name).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCamera(ThermionEntity entity, String? name) =>
|
||||
viewer.setCamera(entity, name).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMainCamera() => viewer.setMainCamera().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getMainCamera() {
|
||||
throw UnimplementedError("TODO");
|
||||
// return viewer.getMainCamera().then((camera) => camera.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setParent(
|
||||
ThermionEntity child, ThermionEntity parent, bool preserveScaling) {
|
||||
return viewer
|
||||
.setParent(child, parent, preserveScaling: preserveScaling)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraFov(double degrees, bool horizontal) =>
|
||||
viewer.setCameraFov(degrees, horizontal: horizontal).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setToneMapping(int mapper) =>
|
||||
viewer.setToneMapping(ToneMapper.values[mapper]).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBloom(double bloom) => viewer.setBloom(bloom).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraFocalLength(double focalLength) =>
|
||||
viewer.setCameraFocalLength(focalLength).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraCulling(double near, double far) =>
|
||||
viewer.setCameraCulling(near, far).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getCameraCullingNear() =>
|
||||
viewer.getCameraCullingNear().then((v) => v.toJS).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getCameraCullingFar() =>
|
||||
viewer.getCameraCullingFar().then((v) => v.toJS).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraFocusDistance(double focusDistance) =>
|
||||
viewer.setCameraFocusDistance(focusDistance).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraPosition() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraPosition().then((position) => position.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraModelMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraModelMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraViewMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraViewMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraProjectionMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraCullingProjectionMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraCullingProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getCameraFrustum() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraFrustum().then((frustum) => frustum.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraPosition(double x, double y, double z) =>
|
||||
viewer.setCameraPosition(x, y, z).toJS;
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraRotation() {
|
||||
return viewer
|
||||
.getCameraRotation()
|
||||
.then((rotation) => rotation.storage.map((v) => v.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise moveCameraToAsset(ThermionEntity entity) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.moveCameraToAsset(entity)).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setViewFrustumCulling(JSBoolean enabled) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.setViewFrustumCulling(enabled).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraExposure(
|
||||
double aperture, double shutterSpeed, double sensitivity) =>
|
||||
viewer.setCameraExposure(aperture, shutterSpeed, sensitivity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraRotation(JSArray<JSNumber> quaternion) {
|
||||
var dartVals = quaternion.toDart;
|
||||
return viewer
|
||||
.setCameraRotation(v64.Quaternion(
|
||||
dartVals[0].toDartDouble,
|
||||
dartVals[1].toDartDouble,
|
||||
dartVals[2].toDartDouble,
|
||||
dartVals[3].toDartDouble))
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraModelMatrix(JSArray<JSNumber> matrix) {
|
||||
throw UnimplementedError();
|
||||
// viewer.setCameraModelMatrix(matrix).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMaterialColor(ThermionEntity entity, String meshName,
|
||||
int materialIndex, double r, double g, double b, double a) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.setMaterialColor(
|
||||
// entity),
|
||||
// meshName,
|
||||
// materialIndex,
|
||||
// r,
|
||||
// g,
|
||||
// b,
|
||||
// a,
|
||||
// ).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise transformToUnitCube(ThermionEntity entity) =>
|
||||
viewer.transformToUnitCube(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setPosition(ThermionEntity entity, double x, double y, double z) =>
|
||||
viewer.setPosition(entity, x, y, z).toJS;
|
||||
@JSExport()
|
||||
JSPromise setScale(ThermionEntity entity, double scale) =>
|
||||
viewer.setScale(entity, scale).toJS;
|
||||
@JSExport()
|
||||
JSPromise setRotation(
|
||||
ThermionEntity entity, double rads, double x, double y, double z) =>
|
||||
viewer.setRotation(entity, rads, x, y, z).toJS;
|
||||
@JSExport()
|
||||
JSPromise queuePositionUpdate(
|
||||
ThermionEntity entity, double x, double y, double z, bool relative) =>
|
||||
viewer
|
||||
.queuePositionUpdate(
|
||||
entity,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
relative: relative,
|
||||
)
|
||||
.toJS;
|
||||
@JSExport()
|
||||
JSPromise queueRotationUpdate(ThermionEntity entity, double rads, double x,
|
||||
double y, double z, bool relative) =>
|
||||
viewer
|
||||
.queueRotationUpdate(
|
||||
entity,
|
||||
rads,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
relative: relative,
|
||||
)
|
||||
.toJS;
|
||||
@JSExport()
|
||||
JSPromise queueRotationUpdateQuat(
|
||||
ThermionEntity entity, JSArray<JSNumber> quat, JSBoolean relative) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.queueRotationUpdateQuat(
|
||||
// entity,
|
||||
// quat.toDartQuaternion(),
|
||||
// relative: relative,
|
||||
// ).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setPostProcessing(bool enabled) =>
|
||||
viewer.setPostProcessing(enabled).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setAntiAliasing(bool msaa, bool fxaa, bool taa) =>
|
||||
viewer.setAntiAliasing(msaa, fxaa, taa).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRotationQuat(
|
||||
ThermionEntity entity, JSArray<JSNumber> rotation) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
@JSExport()
|
||||
JSPromise reveal(ThermionEntity entity, String? meshName) =>
|
||||
viewer.reveal(entity, meshName).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise hide(ThermionEntity entity, String? meshName) =>
|
||||
viewer.hide(entity, meshName).toJS;
|
||||
|
||||
@JSExport()
|
||||
void pick(int x, int y) => viewer.pick(x, y);
|
||||
|
||||
@JSExport()
|
||||
String? getNameForEntity(ThermionEntity entity) =>
|
||||
viewer.getNameForEntity(entity);
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraManipulatorOptions({
|
||||
int mode = 0,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01,
|
||||
}) =>
|
||||
viewer
|
||||
.setCameraManipulatorOptions(
|
||||
mode: ManipulatorMode.values[mode],
|
||||
orbitSpeedX: orbitSpeedX,
|
||||
orbitSpeedY: orbitSpeedY,
|
||||
zoomSpeed: zoomSpeed,
|
||||
)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getChildEntities(
|
||||
ThermionEntity parent, bool renderableOnly) {
|
||||
return viewer
|
||||
.getChildEntities(
|
||||
parent,
|
||||
renderableOnly,
|
||||
)
|
||||
.then((entities) => entities.map((entity) => entity.toJS).toList().toJS)
|
||||
.onError((e, st) async {
|
||||
_logger.severe("Error : $e\n$st");
|
||||
return <JSNumber>[].toJS;
|
||||
}).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getChildEntity(ThermionEntity parent, String childName) {
|
||||
return viewer
|
||||
.getChildEntity(
|
||||
parent,
|
||||
childName,
|
||||
)
|
||||
.then((entity) => entity.toJS)
|
||||
.onError((e, st) async {
|
||||
_logger.severe("Error getChildEntity : $e\n$st");
|
||||
return 0.toJS;
|
||||
}).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getChildEntityNames(
|
||||
ThermionEntity entity, bool renderableOnly) =>
|
||||
viewer
|
||||
.getChildEntityNames(
|
||||
entity,
|
||||
renderableOnly: renderableOnly,
|
||||
)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRecording(bool recording) => viewer.setRecording(recording).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRecordingOutputDirectory(String outputDirectory) =>
|
||||
viewer.setRecordingOutputDirectory(outputDirectory).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise addAnimationComponent(ThermionEntity entity) =>
|
||||
viewer.addAnimationComponent(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeAnimationComponent(ThermionEntity entity) =>
|
||||
viewer.removeAnimationComponent(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise getParent(ThermionEntity entity) =>
|
||||
viewer.removeAnimationComponent(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise getBone(ThermionEntity entity, int boneIndex, int skinIndex) =>
|
||||
viewer.getBone(entity, boneIndex, skinIndex: skinIndex).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getLocalTransform(ThermionEntity entity) {
|
||||
return viewer
|
||||
.getLocalTransform(entity)
|
||||
.then((t) => t.storage.map((v) => v.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getWorldTransform(ThermionEntity entity) {
|
||||
return viewer
|
||||
.getWorldTransform(entity)
|
||||
.then((t) => t.storage.map((v) => v.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setTransform(ThermionEntity entity, JSArray<JSNumber> transform) {
|
||||
return viewer
|
||||
.setTransform(
|
||||
entity,
|
||||
Matrix4.fromList(
|
||||
transform.toDart.map((v) => v.toDartDouble).toList()))
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise updateBoneMatrices(ThermionEntity entity) {
|
||||
return viewer.updateBoneMatrices(entity).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBoneTransform(ThermionEntity entity, int boneIndex,
|
||||
JSArray<JSNumber> transform, int skinIndex) {
|
||||
return viewer
|
||||
.setBoneTransform(
|
||||
entity,
|
||||
boneIndex,
|
||||
Matrix4.fromList(
|
||||
transform.toDart.map((v) => v.toDartDouble).toList()),
|
||||
skinIndex: skinIndex)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise addCollisionComponent(ThermionEntity entity,
|
||||
{JSFunction? callback, bool affectsTransform = false}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setShadowsEnabled(bool enabled) {
|
||||
return viewer.setShadowsEnabled(enabled).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setShadowType(int shadowType) {
|
||||
return viewer.setShadowType(ShadowType.values[shadowType]).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setSoftShadowOptions(
|
||||
double penumbraScale, double penumbraRatioScale) {
|
||||
return viewer.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toJS;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
import 'package:thermion_dart/thermion_dart/viewer/shared_types/camera.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
class ThermionWasmCamera extends Camera {
|
||||
|
||||
final int pointer;
|
||||
|
||||
ThermionWasmCamera(this.pointer);
|
||||
|
||||
@override
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far) {
|
||||
// TODO: implement setProjectionMatrixWithCulling
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,21 +8,27 @@ extern "C"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int32_t EntityId;
|
||||
typedef int32_t _ManipulatorMode;
|
||||
typedef struct TCamera TCamera;
|
||||
typedef struct TMaterialInstance TMaterialInstance;
|
||||
typedef struct TEngine TEngine;
|
||||
typedef struct TEntityManager TEntityManager;
|
||||
typedef struct TViewer TViewer;
|
||||
typedef struct TSceneManager TSceneManager;
|
||||
typedef struct TRenderTarget TRenderTarget;
|
||||
typedef struct TSwapChain TSwapChain;
|
||||
typedef struct TView TView;
|
||||
typedef struct TGizmo TGizmo;
|
||||
typedef struct TScene TScene;
|
||||
|
||||
struct TMaterialKey {
|
||||
bool doubleSided = 1;
|
||||
bool unlit = 1;
|
||||
bool hasVertexColors = 1;
|
||||
bool hasBaseColorTexture = 1;
|
||||
bool hasNormalTexture = 1;
|
||||
bool hasOcclusionTexture = 1;
|
||||
bool hasEmissiveTexture = 1;
|
||||
bool useSpecularGlossiness = 1;
|
||||
bool doubleSided = true;
|
||||
bool unlit = true;
|
||||
bool hasVertexColors = true;
|
||||
bool hasBaseColorTexture = true;
|
||||
bool hasNormalTexture = true;
|
||||
bool hasOcclusionTexture = true;
|
||||
bool hasEmissiveTexture = true;
|
||||
bool useSpecularGlossiness = true;
|
||||
int alphaMode = 4;
|
||||
bool enableDiagnostics = 4;
|
||||
union {
|
||||
@@ -37,42 +43,42 @@ extern "C"
|
||||
};
|
||||
#else
|
||||
struct {
|
||||
bool hasMetallicRoughnessTexture = 1;
|
||||
bool hasMetallicRoughnessTexture = true;
|
||||
uint8_t metallicRoughnessUV = 7;
|
||||
};
|
||||
struct {
|
||||
bool hasSpecularGlossinessTexture = 1;
|
||||
bool hasSpecularGlossinessTexture = true;
|
||||
uint8_t specularGlossinessUV = 7;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
uint8_t baseColorUV;
|
||||
// -- 32 bit boundary --
|
||||
bool hasClearCoatTexture = 1;
|
||||
bool hasClearCoatTexture = true;
|
||||
uint8_t clearCoatUV = 7;
|
||||
bool hasClearCoatRoughnessTexture = 1;
|
||||
bool hasClearCoatRoughnessTexture = true;
|
||||
uint8_t clearCoatRoughnessUV = 7;
|
||||
bool hasClearCoatNormalTexture = 1;
|
||||
bool hasClearCoatNormalTexture = true;
|
||||
uint8_t clearCoatNormalUV = 7;
|
||||
bool hasClearCoat = 1;
|
||||
bool hasTransmission = 1;
|
||||
bool hasClearCoat = true;
|
||||
bool hasTransmission = true;
|
||||
bool hasTextureTransforms = 6;
|
||||
// -- 32 bit boundary --
|
||||
uint8_t emissiveUV;
|
||||
uint8_t aoUV;
|
||||
uint8_t normalUV;
|
||||
bool hasTransmissionTexture = 1;
|
||||
bool hasTransmissionTexture = true;
|
||||
uint8_t transmissionUV = 7;
|
||||
// -- 32 bit boundary --
|
||||
bool hasSheenColorTexture = 1;
|
||||
bool hasSheenColorTexture = true;
|
||||
uint8_t sheenColorUV = 7;
|
||||
bool hasSheenRoughnessTexture = 1;
|
||||
bool hasSheenRoughnessTexture = true;
|
||||
uint8_t sheenRoughnessUV = 7;
|
||||
bool hasVolumeThicknessTexture = 1;
|
||||
bool hasVolumeThicknessTexture = true;
|
||||
uint8_t volumeThicknessUV = 7;
|
||||
bool hasSheen = 1;
|
||||
bool hasIOR = 1;
|
||||
bool hasVolume = 1;
|
||||
bool hasSheen = true;
|
||||
bool hasIOR = true;
|
||||
bool hasVolume = true;
|
||||
} ;
|
||||
typedef struct TMaterialKey TMaterialKey;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <filament/Viewport.h>
|
||||
#include <filament/Frustum.h>
|
||||
|
||||
namespace thermion_filament
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
using namespace filament;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "SceneManager.hpp"
|
||||
#include "ThreadPool.hpp"
|
||||
|
||||
namespace thermion_filament
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
|
||||
@@ -45,13 +45,6 @@ namespace thermion_filament
|
||||
using namespace gltfio;
|
||||
using namespace camutils;
|
||||
|
||||
enum ToneMapping
|
||||
{
|
||||
ACES,
|
||||
FILMIC,
|
||||
LINEAR
|
||||
};
|
||||
|
||||
class FilamentViewer
|
||||
{
|
||||
|
||||
@@ -61,8 +54,9 @@ namespace thermion_filament
|
||||
FilamentViewer(const void *context, const ResourceLoaderWrapperImpl *const resourceLoaderWrapper, void *const platform = nullptr, const char *uberArchivePath = nullptr);
|
||||
~FilamentViewer();
|
||||
|
||||
void setToneMapping(ToneMapping toneMapping);
|
||||
void setBloom(float strength);
|
||||
View* createView();
|
||||
View* getViewAt(int index);
|
||||
|
||||
void loadSkybox(const char *const skyboxUri);
|
||||
void removeSkybox();
|
||||
|
||||
@@ -74,44 +68,37 @@ namespace thermion_filament
|
||||
void removeEntity(EntityId asset);
|
||||
void clearEntities();
|
||||
|
||||
void updateViewport(uint32_t width, uint32_t height);
|
||||
bool render(
|
||||
uint64_t frameTimeInNanos,
|
||||
void *pixelBuffer,
|
||||
void (*callback)(void *buf, size_t size, void *data),
|
||||
void *data);
|
||||
void render(
|
||||
uint64_t frameTimeInNanos
|
||||
);
|
||||
void setFrameInterval(float interval);
|
||||
|
||||
bool setCamera(EntityId asset, const char *nodeName);
|
||||
void setMainCamera();
|
||||
void setMainCamera(View *view);
|
||||
EntityId getMainCamera();
|
||||
Camera* getCamera(EntityId entity);
|
||||
|
||||
float getCameraFov(bool horizontal);
|
||||
void setCameraFov(double fovDegrees, bool horizontal);
|
||||
|
||||
void createSwapChain(const void *surface, uint32_t width, uint32_t height);
|
||||
void destroySwapChain();
|
||||
SwapChain* createSwapChain(const void *surface);
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height);
|
||||
void destroySwapChain(SwapChain* swapChain);
|
||||
|
||||
void createRenderTarget(intptr_t textureId, uint32_t width, uint32_t height);
|
||||
RenderTarget* createRenderTarget(intptr_t textureId, uint32_t width, uint32_t height);
|
||||
void destroyRenderTarget(RenderTarget* renderTarget);
|
||||
|
||||
Renderer *getRenderer();
|
||||
|
||||
std::map<SwapChain*, std::vector<View*>> _renderable;
|
||||
|
||||
void setRenderable(View* view, SwapChain* swapChain, bool renderable);
|
||||
|
||||
void setBackgroundColor(const float r, const float g, const float b, const float a);
|
||||
void setBackgroundImage(const char *resourcePath, bool fillHeight);
|
||||
void setBackgroundImage(const char *resourcePath, bool fillHeight, uint32_t width, uint32_t height);
|
||||
void clearBackgroundImage();
|
||||
void setBackgroundImagePosition(float x, float y, bool clamp);
|
||||
void setBackgroundImagePosition(float x, float y, bool clamp, uint32_t width, uint32_t height);
|
||||
|
||||
void setViewFrustumCulling(bool enabled);
|
||||
|
||||
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, void (*callback)(EntityId entityId, int x, int y));
|
||||
void pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y, View *view));
|
||||
Engine* getEngine() {
|
||||
return _engine;
|
||||
}
|
||||
@@ -137,44 +124,38 @@ namespace thermion_filament
|
||||
void setLightDirection(EntityId entityId, float x, float y, float z);
|
||||
void removeLight(EntityId entityId);
|
||||
void clearLights();
|
||||
void setPostProcessing(bool enabled);
|
||||
|
||||
void setRecording(bool recording);
|
||||
void setRecordingOutputDirectory(const char *path);
|
||||
void capture(uint8_t *out, bool useFence, void (*onComplete)());
|
||||
|
||||
void setAntiAliasing(bool msaaEnabled, bool fxaaEnabled, bool taaEnabled);
|
||||
void setDepthOfField();
|
||||
void setShadowsEnabled(bool enabled);
|
||||
void setShadowType(ShadowType shadowType);
|
||||
void setSoftShadowOptions( float penumbraScale, float penumbraRatioScale);
|
||||
void capture(View* view, uint8_t *out, bool useFence, SwapChain* swapChain, void (*onComplete)());
|
||||
void capture(View* view, uint8_t *out, bool useFence, SwapChain* swapChain, RenderTarget* renderTarget, void (*onComplete)());
|
||||
|
||||
SceneManager *const getSceneManager()
|
||||
{
|
||||
return (SceneManager *const)_sceneManager;
|
||||
}
|
||||
|
||||
SwapChain* getSwapChainAt(int index) {
|
||||
if(index < _swapChains.size()) {
|
||||
return _swapChains[index];
|
||||
}
|
||||
Log("Error: index %d is greater than available swapchains", index);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void unprojectTexture(EntityId entity, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t* out, uint32_t outWidth, uint32_t outHeight);
|
||||
|
||||
private:
|
||||
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
||||
void* _context = nullptr;
|
||||
Scene *_scene = nullptr;
|
||||
|
||||
View *_view = nullptr;
|
||||
|
||||
Engine *_engine = nullptr;
|
||||
thermion_filament::ThreadPool *_tp = nullptr;
|
||||
thermion::ThreadPool *_tp = nullptr;
|
||||
Renderer *_renderer = nullptr;
|
||||
RenderTarget *_rt = nullptr;
|
||||
Texture *_rtColor = nullptr;
|
||||
Texture *_rtDepth = nullptr;
|
||||
|
||||
SwapChain *_swapChain = nullptr;
|
||||
|
||||
SceneManager *_sceneManager = nullptr;
|
||||
std::vector<RenderTarget*> _renderTargets;
|
||||
std::vector<SwapChain*> _swapChains;
|
||||
std::vector<View*> _views;
|
||||
|
||||
std::mutex mtx; // mutex to ensure thread safety when removing assets
|
||||
std::mutex _renderMutex; // mutex to ensure thread safety when removing assets
|
||||
|
||||
std::vector<utils::Entity> _lights;
|
||||
Texture *_skyboxTexture = nullptr;
|
||||
@@ -187,16 +168,6 @@ namespace thermion_filament
|
||||
// Camera properties
|
||||
Camera *_mainCamera = nullptr; // the default camera added to every scene. If you want the *active* camera, access via View.
|
||||
|
||||
Manipulator<double> *_manipulator = nullptr;
|
||||
filament::camutils::Mode _manipulatorMode = filament::camutils::Mode::ORBIT;
|
||||
double _orbitSpeedX = 0.01;
|
||||
double _orbitSpeedY = 0.01;
|
||||
double _zoomSpeed = 0.01;
|
||||
|
||||
void _createManipulator();
|
||||
|
||||
ColorGrading *colorGrading = nullptr;
|
||||
|
||||
// background image properties
|
||||
uint32_t _imageHeight = 0;
|
||||
uint32_t _imageWidth = 0;
|
||||
@@ -215,12 +186,10 @@ namespace thermion_filament
|
||||
void savePng(void *data, size_t size, int frameNumber);
|
||||
void createBackgroundImage();
|
||||
|
||||
time_point_t _recordingStartTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
time_point_t _fpsCounterStartTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
bool _recording = false;
|
||||
std::string _recordingOutputDirectory = std::string("/tmp");
|
||||
std::mutex _recordingMutex;
|
||||
|
||||
std::mutex _imageMutex;
|
||||
double _cumulativeAnimationUpdateTime = 0;
|
||||
int _frameCount = 0;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
|
||||
namespace thermion_filament {
|
||||
namespace thermion {
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
@@ -30,37 +30,12 @@ class Gizmo {
|
||||
|
||||
enum Axis { X, Y, Z};
|
||||
|
||||
class PickCallbackHandler {
|
||||
public:
|
||||
PickCallbackHandler(Gizmo* gizmo, void (*callback)(EntityId entityId, int x, int y)) : _gizmo(gizmo), _callback(callback) {};
|
||||
void handle(filament::View::PickingQueryResult const &result) {
|
||||
auto x = static_cast<int32_t>(result.fragCoords.x);
|
||||
auto y= static_cast<int32_t>(result.fragCoords.y);
|
||||
for(int i = 0; i < 7; i++) {
|
||||
if(_gizmo->_entities[i] == result.renderable) {
|
||||
if(i < 4) {
|
||||
return;
|
||||
}
|
||||
_gizmo->highlight(_gizmo->_entities[i - 4]);
|
||||
_callback(Entity::smuggle(_gizmo->_entities[i - 4]), x, y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_gizmo->unhighlight();
|
||||
_callback(0, x, y);
|
||||
delete(this);
|
||||
}
|
||||
|
||||
private:
|
||||
Gizmo* _gizmo;
|
||||
void (*_callback)(EntityId entityId, int x, int y);
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
Gizmo(Engine& engine, View *view, Scene *scene);
|
||||
Gizmo(Engine *engine, View *view, Scene *scene);
|
||||
~Gizmo();
|
||||
|
||||
typedef void (*PickCallback)(EntityId entityId, uint32_t x, uint32_t y, View *view);
|
||||
|
||||
Entity x() {
|
||||
return _entities[0];
|
||||
};
|
||||
@@ -73,26 +48,49 @@ class Gizmo {
|
||||
Entity center() {
|
||||
return _entities[3];
|
||||
};
|
||||
View* view() {
|
||||
return _view;
|
||||
}
|
||||
|
||||
bool isActive() {
|
||||
return _isActive;
|
||||
}
|
||||
|
||||
void pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||
void pick(uint32_t x, uint32_t y, PickCallback callback);
|
||||
bool isGizmoEntity(Entity entity);
|
||||
void setVisibility(bool visible);
|
||||
|
||||
private:
|
||||
|
||||
class PickCallbackHandler {
|
||||
public:
|
||||
PickCallbackHandler(Gizmo* gizmo, PickCallback callback) : _gizmo(gizmo), _callback(callback) {};
|
||||
void handle(filament::View::PickingQueryResult const &result) {
|
||||
auto x = static_cast<int32_t>(result.fragCoords.x);
|
||||
auto y= static_cast<int32_t>(result.fragCoords.y);
|
||||
for(int i = 0; i < 7; i++) {
|
||||
if(_gizmo->_entities[i] == result.renderable) {
|
||||
if(i < 4) {
|
||||
return;
|
||||
}
|
||||
_gizmo->highlight(_gizmo->_entities[i - 4]);
|
||||
_callback(Entity::smuggle(_gizmo->_entities[i - 4]), x, y, _gizmo->_view);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_gizmo->unhighlight();
|
||||
_callback(0, x, y, _gizmo->_view);
|
||||
delete(this);
|
||||
}
|
||||
|
||||
private:
|
||||
Gizmo* _gizmo;
|
||||
PickCallback _callback;
|
||||
|
||||
};
|
||||
void createTransparentRectangles();
|
||||
void highlight(Entity entity);
|
||||
void unhighlight();
|
||||
Engine &_engine;
|
||||
View *_view;
|
||||
Engine *_engine;
|
||||
Scene *_scene;
|
||||
filament::Camera *_camera;
|
||||
View *_view;
|
||||
utils::Entity _entities[7] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
|
||||
Material* _material;
|
||||
MaterialInstance* _materialInstances[7];
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "material/gizmo.h"
|
||||
|
||||
|
||||
namespace thermion_filament {
|
||||
namespace thermion {
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
using namespace std::chrono_literals;
|
||||
#endif
|
||||
|
||||
namespace thermion_filament
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
struct ResourceLoaderWrapperImpl : public ResourceLoaderWrapper
|
||||
|
||||
@@ -19,10 +19,8 @@
|
||||
#include <filament/InstanceBuffer.h>
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
#include "material/gizmo.h"
|
||||
|
||||
#include "CustomGeometry.hpp"
|
||||
#include "Gizmo.hpp"
|
||||
|
||||
#include "APIBoundaryTypes.h"
|
||||
#include "GridOverlay.hpp"
|
||||
#include "ResourceBuffer.hpp"
|
||||
@@ -32,7 +30,7 @@
|
||||
#include "tsl/robin_map.h"
|
||||
|
||||
|
||||
namespace thermion_filament
|
||||
namespace thermion
|
||||
{
|
||||
typedef int32_t EntityId;
|
||||
|
||||
@@ -46,11 +44,12 @@ namespace thermion_filament
|
||||
class SceneManager
|
||||
{
|
||||
public:
|
||||
SceneManager(View* view,
|
||||
SceneManager(
|
||||
const ResourceLoaderWrapperImpl *const loader,
|
||||
Engine *engine,
|
||||
Scene *scene,
|
||||
const char *uberArchivePath);
|
||||
const char *uberArchivePath,
|
||||
Camera* mainCamera);
|
||||
~SceneManager();
|
||||
|
||||
enum LAYERS {
|
||||
@@ -93,7 +92,7 @@ namespace thermion_filament
|
||||
/// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset.
|
||||
///
|
||||
EntityId loadGlb(const char *uri, int numInstances, bool keepData);
|
||||
EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0);
|
||||
EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false);
|
||||
EntityId createInstance(EntityId entityId);
|
||||
|
||||
void remove(EntityId entity);
|
||||
@@ -108,10 +107,11 @@ namespace thermion_filament
|
||||
void setScale(EntityId e, float scale);
|
||||
void setPosition(EntityId e, float x, float y, float z);
|
||||
void setRotation(EntityId e, float rads, float x, float y, float z, float w);
|
||||
void queuePositionUpdate(EntityId e, float x, float y, float z, bool relative);
|
||||
void queueRotationUpdate(EntityId e, float rads, float x, float y, float z, float w, bool relative);
|
||||
|
||||
void queueTransformUpdates(EntityId* entities, math::mat4* transforms, int numEntities);
|
||||
void queueRelativePositionUpdateWorldAxis(EntityId entity, float viewportCoordX, float viewportCoordY, float x, float y, float z);
|
||||
void queueRelativePositionUpdateFromViewportVector(EntityId entityId, float viewportCoordX, float viewportCoordY);
|
||||
void queueRelativePositionUpdateFromViewportVector(View* view, EntityId entityId, float viewportCoordX, float viewportCoordY);
|
||||
|
||||
const utils::Entity *getCameraEntities(EntityId e);
|
||||
size_t getCameraEntityCount(EntityId e);
|
||||
const utils::Entity *getLightEntities(EntityId e) noexcept;
|
||||
@@ -125,7 +125,7 @@ namespace thermion_filament
|
||||
bool setMorphAnimationBuffer(
|
||||
EntityId entityId,
|
||||
const float *const morphData,
|
||||
const int *const morphIndices,
|
||||
const uint32_t *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs);
|
||||
@@ -170,7 +170,10 @@ namespace thermion_filament
|
||||
|
||||
std::unique_ptr<std::vector<math::mat4f>> getBoneRestTranforms(EntityId entityId, int skinIndex);
|
||||
void resetBones(EntityId entityId);
|
||||
|
||||
bool setTransform(EntityId entityId, math::mat4f transform);
|
||||
bool setTransform(EntityId entityId, math::mat4 transform);
|
||||
|
||||
bool updateBoneMatrices(EntityId entityId);
|
||||
void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f, float startOffset = 0.0f);
|
||||
void stopAnimation(EntityId e, int index);
|
||||
@@ -226,12 +229,7 @@ namespace thermion_filament
|
||||
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
|
||||
/// @return
|
||||
///
|
||||
Aabb2 getBoundingBox(EntityId entity);
|
||||
|
||||
///
|
||||
/// Toggles the visibility of the given layer.
|
||||
///
|
||||
void setLayerVisibility(SceneManager::LAYERS layer, bool enabled);
|
||||
Aabb2 getBoundingBox(View* view, EntityId entity);
|
||||
|
||||
///
|
||||
/// Creates an entity with the specified geometry/material/normals and adds to the scene.
|
||||
@@ -253,8 +251,6 @@ namespace thermion_filament
|
||||
|
||||
friend class FilamentViewer;
|
||||
|
||||
Gizmo* gizmo = nullptr;
|
||||
|
||||
gltfio::MaterialProvider * const unlitMaterialProvider() {
|
||||
return _unlitMaterialProvider;
|
||||
}
|
||||
@@ -267,10 +263,6 @@ namespace thermion_filament
|
||||
return _geometry[entityId].get();
|
||||
}
|
||||
|
||||
Scene* const getScene() {
|
||||
return _scene;
|
||||
}
|
||||
|
||||
bool isGltfAsset(EntityId entity) {
|
||||
return getAssetByEntityId(entity) != nullptr;
|
||||
}
|
||||
@@ -299,12 +291,26 @@ namespace thermion_filament
|
||||
|
||||
void setVisibilityLayer(EntityId entityId, int layer);
|
||||
|
||||
Camera* createCamera();
|
||||
|
||||
void destroyCamera(Camera* camera);
|
||||
|
||||
size_t getCameraCount();
|
||||
|
||||
Camera* getCameraAt(size_t index);
|
||||
|
||||
bool isGizmoEntity(utils::Entity entity);
|
||||
|
||||
Scene* getScene() {
|
||||
return _scene;
|
||||
}
|
||||
|
||||
private:
|
||||
gltfio::AssetLoader *_assetLoader = nullptr;
|
||||
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
||||
Engine *_engine = nullptr;
|
||||
Scene *_scene = nullptr;
|
||||
View* _view = nullptr;
|
||||
Camera* _mainCamera;
|
||||
|
||||
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
|
||||
gltfio::MaterialProvider *_unlitMaterialProvider = nullptr;
|
||||
@@ -313,6 +319,7 @@ namespace thermion_filament
|
||||
gltfio::TextureProvider *_ktxDecoder = nullptr;
|
||||
std::mutex _mutex;
|
||||
std::mutex _stencilMutex;
|
||||
std::vector<MaterialInstance*> _materialInstances;
|
||||
|
||||
utils::NameComponentManager *_ncm;
|
||||
|
||||
@@ -323,8 +330,9 @@ namespace thermion_filament
|
||||
tsl::robin_map<EntityId, gltfio::FilamentAsset *> _assets;
|
||||
tsl::robin_map<EntityId, unique_ptr<CustomGeometry>> _geometry;
|
||||
tsl::robin_map<EntityId, unique_ptr<HighlightOverlay>> _highlighted;
|
||||
tsl::robin_map<EntityId, std::tuple<math::float3, bool, math::quatf, bool, float>> _transformUpdates;
|
||||
tsl::robin_map<EntityId, math::mat4> _transformUpdates;
|
||||
std::set<Texture*> _textures;
|
||||
std::vector<Camera*> _cameras;
|
||||
|
||||
AnimationComponentManager *_animationComponentManager = nullptr;
|
||||
CollisionComponentManager *_collisionComponentManager = nullptr;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace thermion_filament {
|
||||
namespace thermion {
|
||||
|
||||
|
||||
//
|
||||
|
||||
50
thermion_dart/native/include/TCamera.h
Normal file
50
thermion_dart/native/include/TCamera.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace thermion {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
|
||||
enum Projection {
|
||||
Perspective,
|
||||
Orthographic
|
||||
};
|
||||
|
||||
// Camera methods
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_exposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(TCamera *camera, double4x4 matrix);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *get_camera(TViewer *viewer, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_model_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_view_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_projection_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_culling_projection_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE const double *const get_camera_frustum(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_projection_matrix(TCamera *camera, double4x4 matrix, double near, double far);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_near(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_culling_far(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float focusDistance);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, Projection projection, double left, double right,
|
||||
double bottom, double top,
|
||||
double near, double far);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
19
thermion_dart/native/include/TGizmo.h
Normal file
19
thermion_dart/native/include/TGizmo.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
#include "TGizmo.h"
|
||||
|
||||
typedef void (*GizmoPickCallback)(EntityId entityId, uint32_t x, uint32_t y, TView* view);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TGizmo* Gizmo_new(TEngine *tEngine, TView *tView, TScene *tScene);
|
||||
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, uint32_t x, uint32_t y, GizmoPickCallback callback);
|
||||
EMSCRIPTEN_KEEPALIVE void Gizmo_setVisibility(TGizmo *tGizmo, bool visible);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
49
thermion_dart/native/include/TView.h
Normal file
49
thermion_dart/native/include/TView.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace thermion {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
|
||||
struct TViewport {
|
||||
int32_t left;
|
||||
int32_t bottom;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
typedef struct TViewport TViewport;
|
||||
|
||||
enum ToneMapping
|
||||
{
|
||||
ACES,
|
||||
FILMIC,
|
||||
LINEAR
|
||||
};
|
||||
|
||||
// View
|
||||
EMSCRIPTEN_KEEPALIVE TViewport View_getViewport(TView *view);
|
||||
EMSCRIPTEN_KEEPALIVE void View_updateViewport(TView *view, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setRenderTarget(TView *view, TRenderTarget *renderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setFrustumCullingEnabled(TView *view, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_updateViewport(TView* tView, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setRenderTarget(TView* tView, TRenderTarget* tRenderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setFrustumCullingEnabled(TView* tView, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setPostProcessing(TView* tView, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setShadowsEnabled(TView* tView, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setShadowType(TView* tView, int shadowType);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setSoftShadowOptions(TView* tView, float penumbraScale, float penumbraRatioScale);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setBloom(TView* tView, float strength);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setToneMapping(TView* tView, TEngine* tEngine, ToneMapping toneMapping);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setAntiAliasing(TView *tView, bool msaa, bool fxaa, bool taa);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setLayerEnabled(TView *tView, int layer, bool visible);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setCamera(TView *tView, TCamera *tCamera);
|
||||
EMSCRIPTEN_KEEPALIVE TScene* View_getScene(TView *tView);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* View_getCamera(TView *tView);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
27
thermion_dart/native/include/ThermionDartAPIUtils.h
Normal file
27
thermion_dart/native/include/ThermionDartAPIUtils.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <math/mat4.h>
|
||||
#include "APIBoundaryTypes.h"
|
||||
|
||||
namespace thermion {
|
||||
|
||||
// Helper function to convert filament::math::mat4 to double4x4
|
||||
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
|
||||
{
|
||||
return double4x4{
|
||||
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
|
||||
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
|
||||
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
|
||||
{mat[3][0], mat[3][1], mat[3][2], mat[3][3]},
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function to convert double4x4 to filament::math::mat4
|
||||
static filament::math::mat4 convert_double4x4_to_mat4(const double4x4 &d_mat)
|
||||
{
|
||||
return filament::math::mat4{
|
||||
filament::math::float4{float(d_mat.col1[0]), float(d_mat.col1[1]), float(d_mat.col1[2]), float(d_mat.col1[3])},
|
||||
filament::math::float4{float(d_mat.col2[0]), float(d_mat.col2[1]), float(d_mat.col2[2]), float(d_mat.col2[3])},
|
||||
filament::math::float4{float(d_mat.col3[0]), float(d_mat.col3[1]), float(d_mat.col3[2]), float(d_mat.col3[3])},
|
||||
filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}};
|
||||
}
|
||||
}
|
||||
@@ -48,29 +48,58 @@
|
||||
|
||||
#include "APIBoundaryTypes.h"
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "ThermionDartAPIUtils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TViewer *create_filament_viewer(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void *get_scene_manager(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget);
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window);
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createHeadlessSwapChain(TViewer *viewer, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *viewer, TSwapChain* swapChain);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_render(
|
||||
TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
|
||||
TViewer *viewer,
|
||||
TView *view,
|
||||
TSwapChain *swapChain,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void));
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget(
|
||||
TViewer *viewer,
|
||||
TView *view,
|
||||
TSwapChain *swapChain,
|
||||
TRenderTarget *renderTarget,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void));
|
||||
EMSCRIPTEN_KEEPALIVE TView* Viewer_createView(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE TView* Viewer_getViewAt(TViewer *viewer, int index);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView);
|
||||
EMSCRIPTEN_KEEPALIVE TSwapChain* Viewer_getSwapChainAt(TViewer *tViewer, int index);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_setViewRenderable(TViewer *viewer, TSwapChain *swapChain, TView* view, bool renderable);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_pick(TViewer *viewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y, TView *tView));
|
||||
|
||||
// Engine
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_setTransform(TEngine* tEngine, EntityId entity, double4x4 transform);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void create_render_target(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void clear_background_image(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image(TViewer *viewer, const char *path, bool fillHeight);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image_position(TViewer *viewer, float x, float y, bool clamp);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_color(TViewer *viewer, const float r, const float g, const float b, const float a);
|
||||
EMSCRIPTEN_KEEPALIVE void set_tone_mapping(TViewer *viewer, int toneMapping);
|
||||
EMSCRIPTEN_KEEPALIVE void set_bloom(TViewer *viewer, float strength);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath);
|
||||
EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_loadIbl(TViewer *viewer, const char *iblPath, float intensity);
|
||||
EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity);
|
||||
EMSCRIPTEN_KEEPALIVE void rotate_ibl(TViewer *viewer, float *rotationMatrix);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_skybox(TViewer *viewer);
|
||||
@@ -97,69 +126,41 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void clear_lights(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void set_light_position(TViewer *viewer, EntityId light, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void set_light_direction(TViewer *viewer, EntityId light, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId load_glb(void *sceneManager, const char *assetPath, int numInstances, bool keepData);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(void *sceneManager, const void *const data, size_t length, bool keepData, int priority, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(void *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId create_instance(void *sceneManager, EntityId id);
|
||||
EMSCRIPTEN_KEEPALIVE int get_instance_count(void *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void get_instances(void *sceneManager, EntityId entityId, EntityId *out);
|
||||
EMSCRIPTEN_KEEPALIVE void set_main_camera(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId load_glb(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId create_instance(TSceneManager *sceneManager, EntityId id);
|
||||
EMSCRIPTEN_KEEPALIVE int get_instance_count(TSceneManager *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void get_instances(TSceneManager *sceneManager, EntityId entityId, EntityId *out);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_camera(TViewer *viewer, EntityId entity, const char *nodeName);
|
||||
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE bool render(
|
||||
TViewer *viewer,
|
||||
uint64_t frameTimeInNanos,
|
||||
void *pixelBuffer,
|
||||
void (*callback)(void *buf, size_t size, void *data),
|
||||
void *data);
|
||||
EMSCRIPTEN_KEEPALIVE void capture(
|
||||
TViewer *viewer,
|
||||
uint8_t *pixelBuffer,
|
||||
void (*callback)(void));
|
||||
EMSCRIPTEN_KEEPALIVE void create_swap_chain(TViewer *viewer, const void *const window, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_swap_chain(TViewer *viewer);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_frame_interval(TViewer *viewer, float interval);
|
||||
EMSCRIPTEN_KEEPALIVE void update_viewport(TViewer *viewer, uint32_t width, uint32_t height);
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_begin(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_update(TViewer *viewer, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void scroll_end(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void grab_begin(TViewer *viewer, float x, float y, bool pan);
|
||||
EMSCRIPTEN_KEEPALIVE void grab_update(TViewer *viewer, float x, float y);
|
||||
EMSCRIPTEN_KEEPALIVE void grab_end(TViewer *viewer);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void apply_weights(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
const char *const entityName,
|
||||
float *const weights,
|
||||
int count);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_morph_target_weights(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
const float *const morphData,
|
||||
int numWeights);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_morph_animation(
|
||||
void *sceneManager,
|
||||
EntityId entity,
|
||||
const float *const morphData,
|
||||
const int *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(void *const sceneManager, TMaterialKey materialConfig);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(void *const sceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(void *const sceneManager, TMaterialInstance *instance);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(TSceneManager *sceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void clear_morph_animation(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId asset);
|
||||
EMSCRIPTEN_KEEPALIVE void add_bone_animation(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
int skinIndex,
|
||||
int boneIndex,
|
||||
@@ -169,96 +170,92 @@ extern "C"
|
||||
float fadeOutInSecs,
|
||||
float fadeInInSecs,
|
||||
float maxDelta);
|
||||
EMSCRIPTEN_KEEPALIVE void get_local_transform(void *sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void get_local_transform(TSceneManager *sceneManager,
|
||||
EntityId entityId, float *const);
|
||||
EMSCRIPTEN_KEEPALIVE void get_rest_local_transforms(void *sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void get_rest_local_transforms(TSceneManager *sceneManager,
|
||||
EntityId entityId, int skinIndex, float *const out, int numBones);
|
||||
EMSCRIPTEN_KEEPALIVE void get_world_transform(void *sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void get_world_transform(TSceneManager *sceneManager,
|
||||
EntityId entityId, float *const);
|
||||
EMSCRIPTEN_KEEPALIVE void get_inverse_bind_matrix(void *sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void get_inverse_bind_matrix(TSceneManager *sceneManager,
|
||||
EntityId entityId, int skinIndex, int boneIndex, float *const);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_bone_transform(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
int skinIndex,
|
||||
int boneIndex,
|
||||
const float *const transform);
|
||||
EMSCRIPTEN_KEEPALIVE void play_animation(void *sceneManager, EntityId entity, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset);
|
||||
EMSCRIPTEN_KEEPALIVE void set_animation_frame(void *sceneManager, EntityId entity, int animationIndex, int animationFrame);
|
||||
EMSCRIPTEN_KEEPALIVE void stop_animation(void *sceneManager, EntityId entity, int index);
|
||||
EMSCRIPTEN_KEEPALIVE int get_animation_count(void *sceneManager, EntityId asset);
|
||||
EMSCRIPTEN_KEEPALIVE void get_animation_name(void *sceneManager, EntityId entity, char *const outPtr, int index);
|
||||
EMSCRIPTEN_KEEPALIVE float get_animation_duration(void *sceneManager, EntityId entity, int index);
|
||||
EMSCRIPTEN_KEEPALIVE int get_bone_count(void *sceneManager, EntityId assetEntity, int skinIndex);
|
||||
EMSCRIPTEN_KEEPALIVE void get_bone_names(void *sceneManager, EntityId assetEntity, const char **outPtr, int skinIndex);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_bone(void *sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void play_animation(TSceneManager *sceneManager, EntityId entity, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset);
|
||||
EMSCRIPTEN_KEEPALIVE void set_animation_frame(TSceneManager *sceneManager, EntityId entity, int animationIndex, int animationFrame);
|
||||
EMSCRIPTEN_KEEPALIVE void stop_animation(TSceneManager *sceneManager, EntityId entity, int index);
|
||||
EMSCRIPTEN_KEEPALIVE int get_animation_count(TSceneManager *sceneManager, EntityId asset);
|
||||
EMSCRIPTEN_KEEPALIVE void get_animation_name(TSceneManager *sceneManager, EntityId entity, char *const outPtr, int index);
|
||||
EMSCRIPTEN_KEEPALIVE float get_animation_duration(TSceneManager *sceneManager, EntityId entity, int index);
|
||||
EMSCRIPTEN_KEEPALIVE int get_bone_count(TSceneManager *sceneManager, EntityId assetEntity, int skinIndex);
|
||||
EMSCRIPTEN_KEEPALIVE void get_bone_names(TSceneManager *sceneManager, EntityId assetEntity, const char **outPtr, int skinIndex);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_bone(TSceneManager *sceneManager,
|
||||
EntityId entityId,
|
||||
int skinIndex,
|
||||
int boneIndex);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_transform(void *sceneManager, EntityId entityId, const float *const transform);
|
||||
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(void *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name(void *sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index);
|
||||
EMSCRIPTEN_KEEPALIVE int get_morph_target_name_count(void *sceneManager, EntityId assetEntity, EntityId childEntity);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setTransform(TSceneManager *sceneManager, EntityId entityId, const double *const transform);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *sceneManager, EntityId* entities, const double* const transforms, int numEntities);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE TScene* SceneManager_getScene(TSceneManager *tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync);
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setMorphAnimation(
|
||||
TSceneManager *sceneManager,
|
||||
EntityId entity,
|
||||
const float *const morphData,
|
||||
const uint32_t *const morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
float frameLengthInMs);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index);
|
||||
EMSCRIPTEN_KEEPALIVE int get_morph_target_name_count(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_entity(TViewer *viewer, EntityId asset);
|
||||
EMSCRIPTEN_KEEPALIVE void clear_entities(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_material_color(void *sceneManager, EntityId entity, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a);
|
||||
EMSCRIPTEN_KEEPALIVE void transform_to_unit_cube(void *sceneManager, EntityId asset);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update(void *sceneManager, EntityId entity, float x, float y, float z, bool relative);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_relative_position_update_world_axis(void *sceneManager, EntityId entity, float viewportX, float viewportY, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(void *sceneManager, EntityId entity, float viewportX, float viewportY);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_rotation_update(void *sceneManager, EntityId entity, float rads, float x, float y, float z, float w, bool relative);
|
||||
EMSCRIPTEN_KEEPALIVE void set_position(void *sceneManager, EntityId entity, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void set_rotation(void *sceneManager, EntityId entity, float rads, float x, float y, float z, float w);
|
||||
EMSCRIPTEN_KEEPALIVE void set_scale(void *sceneManager, EntityId entity, float scale);
|
||||
EMSCRIPTEN_KEEPALIVE bool set_material_color(TSceneManager *sceneManager, EntityId entity, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a);
|
||||
EMSCRIPTEN_KEEPALIVE void transform_to_unit_cube(TSceneManager *sceneManager, EntityId asset);
|
||||
|
||||
// Camera methods
|
||||
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_exposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(TCamera *camera, double4x4 matrix);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *get_camera(TViewer *viewer, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_model_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_view_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_projection_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_culling_projection_matrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE const double *const get_camera_frustum(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_projection_matrix(TCamera *camera, double4x4 matrix, double near, double far);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_near(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE double get_camera_culling_far(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_lens_projection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float focusDistance);
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_manipulator_options(TViewer *viewer, _ManipulatorMode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *get_camera_component(TEngine *engine, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_relative_position_update_world_axis(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, TView *view, EntityId entity, float viewportX, float viewportY);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_position(TSceneManager *sceneManager, EntityId entity, float x, float y, float z);
|
||||
EMSCRIPTEN_KEEPALIVE void set_rotation(TSceneManager *sceneManager, EntityId entity, float rads, float x, float y, float z, float w);
|
||||
EMSCRIPTEN_KEEPALIVE void set_scale(TSceneManager *sceneManager, EntityId entity, float scale);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
|
||||
|
||||
// SceneManager
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_createCamera(TSceneManager *sceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *sceneManager, TCamera* camera);
|
||||
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *sceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *sceneManager, size_t index);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE int hide_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
|
||||
EMSCRIPTEN_KEEPALIVE int reveal_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(TSceneManager *sceneManager, const EntityId parent, const char *name);
|
||||
EMSCRIPTEN_KEEPALIVE int get_entity_count(TSceneManager *sceneManager, const EntityId target, bool renderableOnly);
|
||||
EMSCRIPTEN_KEEPALIVE void get_entities(TSceneManager *sceneManager, const EntityId target, bool renderableOnly, EntityId *out);
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_entity_name_at(TSceneManager *sceneManager, const EntityId target, int index, bool renderableOnly);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE int hide_mesh(void *sceneManager, EntityId entity, const char *meshName);
|
||||
EMSCRIPTEN_KEEPALIVE int reveal_mesh(void *sceneManager, EntityId entity, const char *meshName);
|
||||
EMSCRIPTEN_KEEPALIVE void set_post_processing(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void set_shadows_enabled(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void set_shadow_type(TViewer *viewer, int shadowType);
|
||||
EMSCRIPTEN_KEEPALIVE void set_soft_shadow_options(TViewer *viewer, float penumbraScale, float penumbraRatioScale);
|
||||
EMSCRIPTEN_KEEPALIVE void set_antialiasing(TViewer *viewer, bool msaa, bool fxaa, bool taa);
|
||||
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *viewer, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(void *const sceneManager, const EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(void *const sceneManager, const EntityId parent, const char *name);
|
||||
EMSCRIPTEN_KEEPALIVE int get_entity_count(void *const sceneManager, const EntityId target, bool renderableOnly);
|
||||
EMSCRIPTEN_KEEPALIVE void get_entities(void *const sceneManager, const EntityId target, bool renderableOnly, EntityId *out);
|
||||
EMSCRIPTEN_KEEPALIVE const char *get_entity_name_at(void *const sceneManager, const EntityId target, int index, bool renderableOnly);
|
||||
EMSCRIPTEN_KEEPALIVE void set_recording(TViewer *viewer, bool recording);
|
||||
EMSCRIPTEN_KEEPALIVE void set_recording_output_directory(TViewer *viewer, const char *outputDirectory);
|
||||
EMSCRIPTEN_KEEPALIVE void ios_dummy();
|
||||
EMSCRIPTEN_KEEPALIVE void thermion_flutter_free(void *ptr);
|
||||
EMSCRIPTEN_KEEPALIVE void add_collision_component(void *const sceneManager, EntityId entityId, void (*callback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_collision_component(void *const sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE bool add_animation_component(void *const sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_animation_component(void *const sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void add_collision_component(TSceneManager *sceneManager, EntityId entityId, void (*callback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_collision_component(TSceneManager *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE bool add_animation_component(TSceneManager *sceneManager, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_animation_component(TSceneManager *sceneManager, EntityId entityId);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId create_geometry(
|
||||
void *const sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
float *vertices,
|
||||
int numVertices,
|
||||
float *normals,
|
||||
@@ -270,33 +267,32 @@ extern "C"
|
||||
int primitiveType,
|
||||
TMaterialInstance *materialInstance,
|
||||
bool keepData);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_parent(void *const sceneManager, EntityId child);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_ancestor(void *const sceneManager, EntityId child);
|
||||
EMSCRIPTEN_KEEPALIVE void set_parent(void *const sceneManager, EntityId child, EntityId parent, bool preserveScaling);
|
||||
EMSCRIPTEN_KEEPALIVE void test_collisions(void *const sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_priority(void *const sceneManager, EntityId entityId, int priority);
|
||||
EMSCRIPTEN_KEEPALIVE void get_gizmo(void *const sceneManager, EntityId *out);
|
||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(void *const sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(void *const sceneManager, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
|
||||
EMSCRIPTEN_KEEPALIVE void set_layer_visibility(void *const sceneManager, int layer, bool visible);
|
||||
EMSCRIPTEN_KEEPALIVE void set_visibility_layer(void *const sceneManager, EntityId entity, int layer);
|
||||
EMSCRIPTEN_KEEPALIVE void pick_gizmo(void *const sceneManager, int x, int y, void (*callback)(EntityId entityId, int x, int y));
|
||||
EMSCRIPTEN_KEEPALIVE void set_gizmo_visibility(void *const sceneManager, bool visible);
|
||||
EMSCRIPTEN_KEEPALIVE void set_stencil_highlight(void *const sceneManager, EntityId entity, float r, float g, float b);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_stencil_highlight(void *const sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_float(void *const sceneManager, EntityId entity, int materialIndex, const char *property, float value);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_int(void *const sceneManager, EntityId entity, int materialIndex, const char *property, int value);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_float4(void *const sceneManager, EntityId entity, int materialIndex, const char *property, double4 value);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_depth_write(void *const sceneManager, EntityId entity, int materialIndex, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer* viewer, EntityId entity,uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight);
|
||||
EMSCRIPTEN_KEEPALIVE void *const create_texture(void *const sceneManager, uint8_t *data, size_t length);
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_texture(void *const sceneManager, void *const texture);
|
||||
EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(void *const sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_parent(TSceneManager *sceneManager, EntityId child);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId get_ancestor(TSceneManager *sceneManager, EntityId child);
|
||||
EMSCRIPTEN_KEEPALIVE void set_parent(TSceneManager *sceneManager, EntityId child, EntityId parent, bool preserveScaling);
|
||||
EMSCRIPTEN_KEEPALIVE void test_collisions(TSceneManager *sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_priority(TSceneManager *sceneManager, EntityId entityId, int priority);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(void *const sceneManager, EntityId entity, int materialIndex);
|
||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *view, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *view, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_stencil_highlight(TSceneManager *sceneManager, EntityId entity, float r, float g, float b);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_stencil_highlight(TSceneManager *sceneManager, EntityId entity);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_float(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, float value);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_int(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, int value);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_property_float4(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, double4 value);
|
||||
EMSCRIPTEN_KEEPALIVE void set_material_depth_write(TSceneManager *sceneManager, EntityId entity, int materialIndex, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer* viewer, EntityId entity,uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight);
|
||||
EMSCRIPTEN_KEEPALIVE void *const create_texture(TSceneManager *sceneManager, uint8_t *data, size_t length);
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_texture(TSceneManager *sceneManager, void *const texture);
|
||||
EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(TSceneManager *sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(TSceneManager *sceneManager, EntityId entity, int materialIndex);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#define _DART_FILAMENT_FFI_API_H
|
||||
|
||||
#include "ThermionDartApi.h"
|
||||
#include "TView.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace thermion {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
@@ -17,7 +19,7 @@ extern "C"
|
||||
typedef int32_t EntityId;
|
||||
typedef void (*FilamentRenderCallback)(void *const owner);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void create_filament_viewer_render_thread(
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
|
||||
void *const context,
|
||||
void *const platform,
|
||||
const char *uberArchivePath,
|
||||
@@ -25,85 +27,69 @@ extern "C"
|
||||
void (*renderCallback)(void *const renderCallbackOwner),
|
||||
void *const renderCallbackOwner,
|
||||
void (*callback)(TViewer *viewer));
|
||||
EMSCRIPTEN_KEEPALIVE void create_swap_chain_render_thread(TViewer *viewer, void *const surface, uint32_t width, uint32_t height, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_swap_chain_render_thread(TViewer *viewer, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void create_render_target_render_thread(TViewer *viewer, intptr_t nativeTextureId, uint32_t width, uint32_t height, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer, void *const surface, void (*onComplete)(TSwapChain*));
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer, uint32_t width, uint32_t height, void (*onComplete)(TSwapChain*));
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChainRenderThread(TViewer *viewer, TSwapChain* swapChain, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain);
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, uint8_t* out, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_loadIblRenderThread(TViewer *viewer, const char *iblPath, float intensity, void(*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, double bloom);
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer_render_thread(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void render_render_thread(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void capture_render_thread(TViewer *viewer, uint8_t* out, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
||||
|
||||
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
||||
EMSCRIPTEN_KEEPALIVE void set_rendering_render_thread(TViewer *viewer, bool rendering, void(*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void request_frame_render_thread(TViewer *viewer);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void set_frame_interval_render_thread(TViewer *viewer, float frameInterval);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_color_render_thread(TViewer *viewer, const float r, const float g, const float b, const float a);
|
||||
EMSCRIPTEN_KEEPALIVE void clear_background_image_render_thread(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image_render_thread(TViewer *viewer, const char *path, bool fillHeight, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void set_background_image_position_render_thread(TViewer *viewer, float x, float y, bool clamp);
|
||||
EMSCRIPTEN_KEEPALIVE void set_tone_mapping_render_thread(TViewer *viewer, int toneMapping);
|
||||
EMSCRIPTEN_KEEPALIVE void set_bloom_render_thread(TViewer *viewer, float strength);
|
||||
EMSCRIPTEN_KEEPALIVE void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void load_ibl_render_thread(TViewer *viewer, const char *iblPath, float intensity);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_skybox_render_thread(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void remove_ibl_render_thread(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void add_light_render_thread(
|
||||
TViewer *viewer,
|
||||
uint8_t type,
|
||||
float colour,
|
||||
float intensity,
|
||||
float posX,
|
||||
float posY,
|
||||
float posZ,
|
||||
float dirX,
|
||||
float dirY,
|
||||
float dirZ,
|
||||
float falloffRadius,
|
||||
float spotLightConeInner,
|
||||
float spotLightConeOuter,
|
||||
float sunAngularRadius,
|
||||
float sunHaloSize,
|
||||
float sunHaloFallof,
|
||||
bool shadows,
|
||||
void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void remove_light_render_thread(TViewer *viewer, EntityId entityId);
|
||||
EMSCRIPTEN_KEEPALIVE void clear_lights_render_thread(TViewer *viewer);
|
||||
EMSCRIPTEN_KEEPALIVE void load_glb_render_thread(void *const sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void load_glb_from_buffer_render_thread(void *const sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void load_gltf_render_thread(void *const sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void create_instance_render_thread(void *const sceneManager, EntityId entityId, void (*callback)(EntityId));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
|
||||
EMSCRIPTEN_KEEPALIVE void remove_entity_render_thread(TViewer *viewer, EntityId asset, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void clear_entities_render_thread(TViewer *viewer, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void set_camera_render_thread(TViewer *viewer, EntityId asset, const char *nodeName, void (*callback)(bool));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void apply_weights_render_thread(
|
||||
void *const sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId asset,
|
||||
const char *const entityName,
|
||||
float *const weights,
|
||||
int count);
|
||||
EMSCRIPTEN_KEEPALIVE void set_animation_frame_render_thread(void *const sceneManager, EntityId asset, int animationIndex, int animationFrame);
|
||||
EMSCRIPTEN_KEEPALIVE void stop_animation_render_thread(void *const sceneManager, EntityId asset, int index);
|
||||
EMSCRIPTEN_KEEPALIVE void get_animation_count_render_thread(void *const sceneManager, EntityId asset, void (*callback)(int));
|
||||
EMSCRIPTEN_KEEPALIVE void get_animation_name_render_thread(void *const sceneManager, EntityId asset, char *const outPtr, int index, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name_render_thread(void *const sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name_count_render_thread(void *const sceneManager, EntityId asset, EntityId childEntity, void (*callback)(int32_t));
|
||||
EMSCRIPTEN_KEEPALIVE void set_morph_target_weights_render_thread(void *const sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void set_animation_frame_render_thread(TSceneManager *sceneManager, EntityId asset, int animationIndex, int animationFrame);
|
||||
EMSCRIPTEN_KEEPALIVE void stop_animation_render_thread(TSceneManager *sceneManager, EntityId asset, int index);
|
||||
EMSCRIPTEN_KEEPALIVE void get_animation_count_render_thread(TSceneManager *sceneManager, EntityId asset, void (*callback)(int));
|
||||
EMSCRIPTEN_KEEPALIVE void get_animation_name_render_thread(TSceneManager *sceneManager, EntityId asset, char *const outPtr, int index, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name_render_thread(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void get_morph_target_name_count_render_thread(TSceneManager *sceneManager, EntityId asset, EntityId childEntity, void (*callback)(int32_t));
|
||||
EMSCRIPTEN_KEEPALIVE void set_morph_target_weights_render_thread(TSceneManager *sceneManager,
|
||||
EntityId asset,
|
||||
const float *const morphData,
|
||||
int numWeights,
|
||||
void (*callback)(bool));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void update_bone_matrices_render_thread(void *sceneManager,
|
||||
EMSCRIPTEN_KEEPALIVE void update_bone_matrices_render_thread(TSceneManager *sceneManager,
|
||||
EntityId asset, void(*callback)(bool));
|
||||
EMSCRIPTEN_KEEPALIVE void set_bone_transform_render_thread(
|
||||
void *sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
EntityId asset,
|
||||
int skinIndex,
|
||||
int boneIndex,
|
||||
const float *const transform,
|
||||
void (*callback)(bool));
|
||||
EMSCRIPTEN_KEEPALIVE void set_post_processing_render_thread(TViewer *viewer, bool enabled);
|
||||
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose_render_thread(void *const sceneManager, EntityId entityId, void(*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void(*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void create_geometry_render_thread(
|
||||
void *const sceneManager,
|
||||
TSceneManager *sceneManager,
|
||||
float *vertices,
|
||||
int numVertices,
|
||||
float *normals,
|
||||
@@ -121,6 +107,7 @@ extern "C"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _DART_FILAMENT_FFI_API_H
|
||||
|
||||
36
thermion_dart/native/include/ThermionWin32.h
Normal file
36
thermion_dart/native/include/ThermionWin32.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
#pragma comment(lib, "gdi32.lib")
|
||||
#pragma comment(lib, "user32.lib")
|
||||
#pragma comment(lib, "shell32.lib")
|
||||
#pragma comment(lib, "dwmapi.lib")
|
||||
#pragma comment(lib, "comctl32.lib")
|
||||
#pragma comment(lib, "filament.lib")
|
||||
#pragma comment(lib, "bluevk.lib")
|
||||
#pragma comment(lib, "bluegl.lib")
|
||||
#pragma comment(lib, "backend.lib")
|
||||
#pragma comment(lib, "filameshio.lib")
|
||||
#pragma comment(lib, "viewer.lib")
|
||||
#pragma comment(lib, "filamat.lib")
|
||||
#pragma comment(lib, "geometry.lib")
|
||||
#pragma comment(lib, "utils.lib")
|
||||
#pragma comment(lib, "filabridge.lib")
|
||||
#pragma comment(lib, "gltfio_core.lib")
|
||||
#pragma comment(lib, "filament-iblprefilter.lib")
|
||||
#pragma comment(lib, "image.lib")
|
||||
#pragma comment(lib, "imageio.lib")
|
||||
#pragma comment(lib, "tinyexr.lib")
|
||||
#pragma comment(lib, "filaflat.lib")
|
||||
#pragma comment(lib, "dracodec.lib")
|
||||
#pragma comment(lib, "ibl.lib")
|
||||
#pragma comment(lib, "ktxreader.lib")
|
||||
#pragma comment(lib, "png.lib")
|
||||
#pragma comment(lib, "z.lib")
|
||||
#pragma comment(lib, "stb.lib")
|
||||
#pragma comment(lib, "uberzlib.lib")
|
||||
#pragma comment(lib, "smol-v.lib")
|
||||
#pragma comment(lib, "uberarchive.lib")
|
||||
#pragma comment(lib, "zstd.lib")
|
||||
#pragma comment(lib, "basis_transcoder.lib")
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef _THREADPOOL_HPP
|
||||
#define _THREADPOOL_HPP
|
||||
|
||||
namespace thermion_filament {
|
||||
namespace thermion {
|
||||
|
||||
class ThreadPool {
|
||||
std::vector<std::thread> pool;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "CustomGeometry.hpp"
|
||||
|
||||
namespace thermion_filament {
|
||||
namespace thermion {
|
||||
|
||||
class UnprojectTexture {
|
||||
public:
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
template class std::vector<float>;
|
||||
namespace thermion_filament
|
||||
namespace thermion
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace filament::gltfio;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "gltfio/FilamentInstance.h"
|
||||
#include "Log.hpp"
|
||||
|
||||
namespace thermion_filament
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
typedef void(*CollisionCallback)(int32_t entityId1, int32_t entityId2) ;
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
// Generated by Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
|
||||
#ifndef SWIFT_MODULE_SWIFT_H
|
||||
#define SWIFT_MODULE_SWIFT_H
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgcc-compat"
|
||||
|
||||
#if !defined(__has_include)
|
||||
# define __has_include(x) 0
|
||||
#endif
|
||||
#if !defined(__has_attribute)
|
||||
# define __has_attribute(x) 0
|
||||
#endif
|
||||
#if !defined(__has_feature)
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
#if !defined(__has_warning)
|
||||
# define __has_warning(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_include(<swift/objc-prologue.h>)
|
||||
# include <swift/objc-prologue.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic ignored "-Wauto-import"
|
||||
#if defined(__OBJC__)
|
||||
#include <Foundation/Foundation.h>
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <cstdbool>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
#if defined(__arm64e__) && __has_include(<ptrauth.h>)
|
||||
# include <ptrauth.h>
|
||||
#else
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
|
||||
# ifndef __ptrauth_swift_value_witness_function_pointer
|
||||
# define __ptrauth_swift_value_witness_function_pointer(x)
|
||||
# endif
|
||||
# ifndef __ptrauth_swift_class_method_pointer
|
||||
# define __ptrauth_swift_class_method_pointer(x)
|
||||
# endif
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_TYPEDEFS)
|
||||
# define SWIFT_TYPEDEFS 1
|
||||
# if __has_include(<uchar.h>)
|
||||
# include <uchar.h>
|
||||
# elif !defined(__cplusplus)
|
||||
typedef uint_least16_t char16_t;
|
||||
typedef uint_least32_t char32_t;
|
||||
# endif
|
||||
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_PASTE)
|
||||
# define SWIFT_PASTE_HELPER(x, y) x##y
|
||||
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
|
||||
#endif
|
||||
#if !defined(SWIFT_METATYPE)
|
||||
# define SWIFT_METATYPE(X) Class
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS_PROPERTY)
|
||||
# if __has_feature(objc_class_property)
|
||||
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
|
||||
# else
|
||||
# define SWIFT_CLASS_PROPERTY(...)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_RUNTIME_NAME)
|
||||
# if __has_attribute(objc_runtime_name)
|
||||
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
|
||||
# else
|
||||
# define SWIFT_RUNTIME_NAME(X)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_COMPILE_NAME)
|
||||
# if __has_attribute(swift_name)
|
||||
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
|
||||
# else
|
||||
# define SWIFT_COMPILE_NAME(X)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_METHOD_FAMILY)
|
||||
# if __has_attribute(objc_method_family)
|
||||
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
|
||||
# else
|
||||
# define SWIFT_METHOD_FAMILY(X)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_NOESCAPE)
|
||||
# if __has_attribute(noescape)
|
||||
# define SWIFT_NOESCAPE __attribute__((noescape))
|
||||
# else
|
||||
# define SWIFT_NOESCAPE
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_RELEASES_ARGUMENT)
|
||||
# if __has_attribute(ns_consumed)
|
||||
# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
|
||||
# else
|
||||
# define SWIFT_RELEASES_ARGUMENT
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_WARN_UNUSED_RESULT)
|
||||
# if __has_attribute(warn_unused_result)
|
||||
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
# else
|
||||
# define SWIFT_WARN_UNUSED_RESULT
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_NORETURN)
|
||||
# if __has_attribute(noreturn)
|
||||
# define SWIFT_NORETURN __attribute__((noreturn))
|
||||
# else
|
||||
# define SWIFT_NORETURN
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS_EXTRA)
|
||||
# define SWIFT_CLASS_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_PROTOCOL_EXTRA)
|
||||
# define SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM_EXTRA)
|
||||
# define SWIFT_ENUM_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS)
|
||||
# if __has_attribute(objc_subclassing_restricted)
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# else
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_RESILIENT_CLASS)
|
||||
# if __has_attribute(objc_class_stub)
|
||||
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
|
||||
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
|
||||
# else
|
||||
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
|
||||
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_PROTOCOL)
|
||||
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_EXTENSION)
|
||||
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
|
||||
#endif
|
||||
#if !defined(OBJC_DESIGNATED_INITIALIZER)
|
||||
# if __has_attribute(objc_designated_initializer)
|
||||
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
# else
|
||||
# define OBJC_DESIGNATED_INITIALIZER
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM_ATTR)
|
||||
# if __has_attribute(enum_extensibility)
|
||||
# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
|
||||
# else
|
||||
# define SWIFT_ENUM_ATTR(_extensibility)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM)
|
||||
# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
|
||||
# if __has_feature(generalized_swift_name)
|
||||
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
|
||||
# else
|
||||
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_UNAVAILABLE)
|
||||
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
|
||||
#endif
|
||||
#if !defined(SWIFT_UNAVAILABLE_MSG)
|
||||
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
|
||||
#endif
|
||||
#if !defined(SWIFT_AVAILABILITY)
|
||||
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
|
||||
#endif
|
||||
#if !defined(SWIFT_WEAK_IMPORT)
|
||||
# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
|
||||
#endif
|
||||
#if !defined(SWIFT_DEPRECATED)
|
||||
# define SWIFT_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#if !defined(SWIFT_DEPRECATED_MSG)
|
||||
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
|
||||
#endif
|
||||
#if !defined(SWIFT_DEPRECATED_OBJC)
|
||||
# if __has_feature(attribute_diagnose_if_objc)
|
||||
# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
|
||||
# else
|
||||
# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__OBJC__)
|
||||
#if !defined(IBSegueAction)
|
||||
# define IBSegueAction
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SWIFT_EXTERN)
|
||||
# if defined(__cplusplus)
|
||||
# define SWIFT_EXTERN extern "C"
|
||||
# else
|
||||
# define SWIFT_EXTERN extern
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_CALL)
|
||||
# define SWIFT_CALL __attribute__((swiftcall))
|
||||
#endif
|
||||
#if !defined(SWIFT_INDIRECT_RESULT)
|
||||
# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result))
|
||||
#endif
|
||||
#if !defined(SWIFT_CONTEXT)
|
||||
# define SWIFT_CONTEXT __attribute__((swift_context))
|
||||
#endif
|
||||
#if !defined(SWIFT_ERROR_RESULT)
|
||||
# define SWIFT_ERROR_RESULT __attribute__((swift_error_result))
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
# define SWIFT_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SWIFT_NOEXCEPT
|
||||
#endif
|
||||
#if !defined(SWIFT_C_INLINE_THUNK)
|
||||
# if __has_attribute(always_inline)
|
||||
# if __has_attribute(nodebug)
|
||||
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug))
|
||||
# else
|
||||
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline))
|
||||
# endif
|
||||
# else
|
||||
# define SWIFT_C_INLINE_THUNK inline
|
||||
# endif
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
|
||||
# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
|
||||
# define SWIFT_IMPORT_STDLIB_SYMBOL
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__OBJC__)
|
||||
#if __has_feature(objc_modules)
|
||||
#if __has_warning("-Watimport-in-framework-header")
|
||||
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
|
||||
#endif
|
||||
@import CoreVideo;
|
||||
@import ObjectiveC;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
|
||||
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
|
||||
#if __has_warning("-Wpragma-clang-attribute")
|
||||
# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wnullability"
|
||||
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
|
||||
|
||||
#if __has_attribute(external_source_symbol)
|
||||
# pragma push_macro("any")
|
||||
# undef any
|
||||
# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="swift_module",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
|
||||
# pragma pop_macro("any")
|
||||
#endif
|
||||
|
||||
#if defined(__OBJC__)
|
||||
@protocol MTLDevice;
|
||||
@protocol MTLTexture;
|
||||
@class NSData;
|
||||
|
||||
SWIFT_CLASS("_TtC12swift_module20ThermionTextureSwift")
|
||||
@interface ThermionTextureSwift : NSObject
|
||||
@property (nonatomic) CVMetalTextureCacheRef _Nullable cvMetalTextureCache;
|
||||
@property (nonatomic, strong) id <MTLDevice> _Nullable metalDevice;
|
||||
@property (nonatomic) CVMetalTextureRef _Nullable cvMetalTexture;
|
||||
@property (nonatomic, strong) id <MTLTexture> _Nullable metalTexture;
|
||||
@property (nonatomic) NSInteger metalTextureAddress;
|
||||
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
|
||||
- (nonnull instancetype)initWithWidth:(int64_t)width height:(int64_t)height OBJC_DESIGNATED_INITIALIZER;
|
||||
- (void)destroyTexture;
|
||||
- (void)fillColor;
|
||||
- (NSData * _Nullable)getTextureBytes SWIFT_WARN_UNUSED_RESULT;
|
||||
@end
|
||||
|
||||
#endif
|
||||
#if __has_attribute(external_source_symbol)
|
||||
# pragma clang attribute pop
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
#endif
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user