Merge branch 'develop' of https://github.com/nmfisher/thermion into develop
This commit is contained in:
109
CHANGELOG.md
109
CHANGELOG.md
@@ -3,6 +3,115 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## 2024-10-31
|
||||||
|
|
||||||
|
### 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.16`](#thermion_dart---v021-dev0016)
|
||||||
|
- [`thermion_flutter` - `v0.2.1-dev.16`](#thermion_flutter---v021-dev16)
|
||||||
|
- [`thermion_flutter_web` - `v0.2.0+7`](#thermion_flutter_web---v0207)
|
||||||
|
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.16`](#thermion_flutter_platform_interface---v021-dev16)
|
||||||
|
- [`thermion_flutter_ffi` - `v0.2.1-dev.16`](#thermion_flutter_ffi---v021-dev16)
|
||||||
|
|
||||||
|
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.1-dev.16`
|
||||||
|
- `thermion_flutter_web` - `v0.2.0+7`
|
||||||
|
- `thermion_flutter_platform_interface` - `v0.2.1-dev.16`
|
||||||
|
- `thermion_flutter_ffi` - `v0.2.1-dev.16`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `thermion_dart` - `v0.2.1-dev.0.0.16`
|
||||||
|
|
||||||
|
- **FEAT**: Rename Gizmo material to UnlitFixedSize, and expose methods for using this material on other entities. Also exposes new methods for setting single float parameters.
|
||||||
|
|
||||||
|
|
||||||
|
## 2024-10-31
|
||||||
|
|
||||||
|
### 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.15`](#thermion_dart---v021-dev0015)
|
||||||
|
- [`thermion_flutter` - `v0.2.1-dev.15`](#thermion_flutter---v021-dev15)
|
||||||
|
- [`thermion_flutter_web` - `v0.2.0+6`](#thermion_flutter_web---v0206)
|
||||||
|
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.15`](#thermion_flutter_platform_interface---v021-dev15)
|
||||||
|
- [`thermion_flutter_ffi` - `v0.2.1-dev.15`](#thermion_flutter_ffi---v021-dev15)
|
||||||
|
|
||||||
|
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.2.0+6`
|
||||||
|
- `thermion_flutter_platform_interface` - `v0.2.1-dev.15`
|
||||||
|
- `thermion_flutter_ffi` - `v0.2.1-dev.15`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `thermion_dart` - `v0.2.1-dev.0.0.15`
|
||||||
|
|
||||||
|
- **FIX**: remove superfluous ceil() calls for picking coordinates.
|
||||||
|
- **FEAT**: expose zoomSensitivity argument for flight input handler.
|
||||||
|
|
||||||
|
#### `thermion_flutter` - `v0.2.1-dev.15`
|
||||||
|
|
||||||
|
- **FIX**: multiply coordinates by pixelRatio for scale events.
|
||||||
|
|
||||||
|
|
||||||
|
## 2024-10-30
|
||||||
|
|
||||||
|
### 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.14`](#thermion_dart---v021-dev0014)
|
||||||
|
- [`thermion_flutter` - `v0.2.1-dev.14`](#thermion_flutter---v021-dev14)
|
||||||
|
- [`thermion_flutter_platform_interface` - `v0.2.1-dev.14`](#thermion_flutter_platform_interface---v021-dev14)
|
||||||
|
- [`thermion_flutter_ffi` - `v0.2.1-dev.14`](#thermion_flutter_ffi---v021-dev14)
|
||||||
|
- [`thermion_flutter_web` - `v0.2.0+5`](#thermion_flutter_web---v0205)
|
||||||
|
|
||||||
|
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.1-dev.14`
|
||||||
|
- `thermion_flutter_platform_interface` - `v0.2.1-dev.14`
|
||||||
|
- `thermion_flutter_ffi` - `v0.2.1-dev.14`
|
||||||
|
- `thermion_flutter_web` - `v0.2.0+5`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `thermion_dart` - `v0.2.1-dev.0.0.14`
|
||||||
|
|
||||||
|
- **FIX**: reduce size of pick functor for compatibility with armeabi-v7a.
|
||||||
|
- **FEAT**: sanitize file paths in build.dart for Windows compatibility.
|
||||||
|
- **FEAT**: pass through fragment coordinates for picking.
|
||||||
|
- **FEAT**: pass through fragment coordinates for picking.
|
||||||
|
|
||||||
|
|
||||||
## 2024-10-29
|
## 2024-10-29
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -23,7 +23,7 @@ bindings:
|
|||||||
#
|
#
|
||||||
materials: FORCE
|
materials: FORCE
|
||||||
@echo "Using Filament build from ${FILAMENT_PATH}"
|
@echo "Using Filament build from ${FILAMENT_PATH}"
|
||||||
@for material in unlit image gizmo grid; do \
|
@for material in unlit image unlit_fixed_size grid; do \
|
||||||
${FILAMENT_PATH}/matc -a opengl -a metal -o materials/$$material.filamat materials/$$material.mat; \
|
${FILAMENT_PATH}/matc -a opengl -a metal -o materials/$$material.filamat materials/$$material.mat; \
|
||||||
$(FILAMENT_PATH)/resgen -c -p $$material -x thermion_dart/native/include/material/ materials/$$material.filamat; \
|
$(FILAMENT_PATH)/resgen -c -p $$material -x thermion_dart/native/include/material/ materials/$$material.filamat; \
|
||||||
echo '#include "'$$material'.h"' | cat - thermion_dart/native/include/material/$$material.c > thermion_dart/native/include/material/$$material.c.new; \
|
echo '#include "'$$material'.h"' | cat - thermion_dart/native/include/material/$$material.c > thermion_dart/native/include/material/$$material.c.new; \
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -3,7 +3,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://thermion.dev/quickstart">Quickstart (Flutter)</a> •
|
<a href="https://thermion.dev/quickstart">Quickstart (Flutter)</a> •
|
||||||
<a href="https://thermion.dev/">Documentation</a> •
|
<a href="https://thermion.dev/">Documentation</a> •
|
||||||
<a href="https://thermion.dev/examples">Showcase</a> •
|
<a href="https://thermion.dev/showcase">Showcase</a> •
|
||||||
<a href="https://dartpad.thermion.dev/">Playground</a> •
|
<a href="https://dartpad.thermion.dev/">Playground</a> •
|
||||||
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
|
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -24,13 +24,17 @@
|
|||||||
|
|
||||||
### Quickstart (Flutter)
|
### Quickstart (Flutter)
|
||||||
|
|
||||||
```
|
From the command line:
|
||||||
|
|
||||||
|
```bash
|
||||||
flutter channel master
|
flutter channel master
|
||||||
flutter upgrade
|
flutter upgrade
|
||||||
flutter config --enable-native-assets
|
flutter config --enable-native-assets
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
In your Flutter app:
|
||||||
|
|
||||||
|
```dart
|
||||||
_thermionViewer = await ThermionFlutterPlugin.createViewer();
|
_thermionViewer = await ThermionFlutterPlugin.createViewer();
|
||||||
|
|
||||||
// Geometry and models are represented as "entities". Here, we load a glTF
|
// Geometry and models are represented as "entities". Here, we load a glTF
|
||||||
@@ -61,8 +65,8 @@ await _thermionViewer!.loadIbl("assets/default_env_ibl.ktx");
|
|||||||
await _thermionViewer!.setRendering(true);
|
await _thermionViewer!.setRendering(true);
|
||||||
```
|
```
|
||||||
|
|
||||||
and then in your Flutter application:
|
and then in your widget tree:
|
||||||
```
|
```dart
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Stack(children: [
|
return Stack(children: [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
material {
|
material {
|
||||||
name : Gizmo,
|
name : UnlitFixedSize,
|
||||||
parameters : [
|
parameters : [
|
||||||
{
|
{
|
||||||
type : mat4,
|
type : mat4,
|
||||||
@@ -8,8 +8,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type : float4,
|
type : float4,
|
||||||
name : color,
|
name : baseColorFactor,
|
||||||
precision : low
|
precision : low
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: float, // the number of world-space units between the camera and the (unscaled) gizmo
|
||||||
|
name: scale,
|
||||||
|
precision: low
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
depthWrite : true,
|
depthWrite : true,
|
||||||
@@ -24,14 +29,13 @@
|
|||||||
|
|
||||||
vertex {
|
vertex {
|
||||||
void materialVertex(inout MaterialVertexInputs material) {
|
void materialVertex(inout MaterialVertexInputs material) {
|
||||||
|
// the object should have the same size (in screen-space), no matter the distance from the camera
|
||||||
// we want to ensure the gizmo has the same size (in screen-space), no matter the distance from the camera
|
// scale the model-space vertex positions by the distance from the camera
|
||||||
// we do this by scaling the model-space vertex positions by the distance from the camera
|
|
||||||
vec4 modelSpace = getPosition();
|
vec4 modelSpace = getPosition();
|
||||||
vec4 worldSpace = getWorldFromModelMatrix() * modelSpace;
|
vec4 worldSpace = getWorldFromModelMatrix() * modelSpace;
|
||||||
vec4 viewSpace = getViewFromWorldMatrix() * worldSpace;
|
vec4 viewSpace = getViewFromWorldMatrix() * worldSpace;
|
||||||
float distanceFromCamera = length(viewSpace.xyz);
|
float distanceFromCamera = length(viewSpace.xyz);
|
||||||
modelSpace.xyz *= (distanceFromCamera / 4.0f); // divide by 4 so that the size is equivalent to the camera being 4 world-space units away from the (unscaled) gizmo
|
modelSpace.xyz *= (distanceFromCamera / materialParams.scale);
|
||||||
|
|
||||||
worldSpace = getWorldFromModelMatrix() * modelSpace;
|
worldSpace = getWorldFromModelMatrix() * modelSpace;
|
||||||
material.worldPosition = worldSpace;
|
material.worldPosition = worldSpace;
|
||||||
@@ -44,7 +48,7 @@
|
|||||||
fragment {
|
fragment {
|
||||||
void material(inout MaterialInputs material) {
|
void material(inout MaterialInputs material) {
|
||||||
prepareMaterial(material);
|
prepareMaterial(material);
|
||||||
material.baseColor = materialParams.color;
|
material.baseColor = materialParams.baseColorFactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,3 +1,19 @@
|
|||||||
|
## 0.2.1-dev.0.0.16
|
||||||
|
|
||||||
|
- **FEAT**: Rename Gizmo material to UnlitFixedSize, and expose methods for using this material on other entities. Also exposes new methods for setting single float parameters.
|
||||||
|
|
||||||
|
## 0.2.1-dev.0.0.15
|
||||||
|
|
||||||
|
- **FIX**: remove superfluous ceil() calls for picking coordinates.
|
||||||
|
- **FEAT**: expose zoomSensitivity argument for flight input handler.
|
||||||
|
|
||||||
|
## 0.2.1-dev.0.0.14
|
||||||
|
|
||||||
|
- **FIX**: reduce size of pick functor for compatibility with armeabi-v7a.
|
||||||
|
- **FEAT**: sanitize file paths in build.dart for Windows compatibility.
|
||||||
|
- **FEAT**: pass through fragment coordinates for picking.
|
||||||
|
- **FEAT**: pass through fragment coordinates for picking.
|
||||||
|
|
||||||
## 0.2.1-dev.0.0.13
|
## 0.2.1-dev.0.0.13
|
||||||
|
|
||||||
- **FIX**: properly pass through loadResourcesAsync flag for loadGlbFromBuffer.
|
- **FIX**: properly pass through loadResourcesAsync flag for loadGlbFromBuffer.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://thermion.dev/quickstart">Quickstart (Flutter)</a> •
|
<a href="https://thermion.dev/quickstart">Quickstart (Flutter)</a> •
|
||||||
<a href="https://thermion.dev/quickstart">Documentation</a> •
|
<a href="https://thermion.dev/quickstart">Documentation</a> •
|
||||||
<a href="https://thermion.dev/examples">Showcase</a> •
|
<a href="https://thermion.dev/showcase">Showcase</a> •
|
||||||
<a href="https://dartpad.thermion.dev/">Playground</a> •
|
<a href="https://dartpad.thermion.dev/">Playground</a> •
|
||||||
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
|
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void main(List<String> args) async {
|
|||||||
.map((f) => f.path)
|
.map((f) => f.path)
|
||||||
.toList();
|
.toList();
|
||||||
sources.addAll([
|
sources.addAll([
|
||||||
path.join(pkgRootFilePath, "native", "include", "material", "gizmo_material.c"),
|
path.join(pkgRootFilePath, "native", "include", "material", "unlit_fixed_size.c"),
|
||||||
path.join(pkgRootFilePath, "native", "include", "material", "image.c"),
|
path.join(pkgRootFilePath, "native", "include", "material", "image.c"),
|
||||||
path.join(pkgRootFilePath, "native", "include", "material", "grid.c"),
|
path.join(pkgRootFilePath, "native", "include", "material", "grid.c"),
|
||||||
path.join(pkgRootFilePath, "native", "include", "material", "unlit.c"),
|
path.join(pkgRootFilePath, "native", "include", "material", "unlit.c"),
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
{PickDelegate? pickDelegate,
|
{PickDelegate? pickDelegate,
|
||||||
bool freeLook = false,
|
bool freeLook = false,
|
||||||
double panSensitivity = 0.1,
|
double panSensitivity = 0.1,
|
||||||
|
double zoomSensitivity = 0.1,
|
||||||
double movementSensitivity = 0.1,
|
double movementSensitivity = 0.1,
|
||||||
double rotateSensitivity = 0.01,
|
double rotateSensitivity = 0.01,
|
||||||
double? clampY,
|
double? clampY,
|
||||||
@@ -93,6 +94,7 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
clampY: clampY,
|
clampY: clampY,
|
||||||
entity: entity,
|
entity: entity,
|
||||||
rotationSensitivity: rotateSensitivity,
|
rotationSensitivity: rotateSensitivity,
|
||||||
|
zoomSensitivity:zoomSensitivity,
|
||||||
panSensitivity: panSensitivity,
|
panSensitivity: panSensitivity,
|
||||||
movementSensitivity: movementSensitivity),
|
movementSensitivity: movementSensitivity),
|
||||||
actions: {
|
actions: {
|
||||||
|
|||||||
@@ -621,6 +621,15 @@ external int get_bone(
|
|||||||
int boneIndex,
|
int boneIndex,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Pointer<TGizmo> Function(ffi.Pointer<TSceneManager>, ffi.Pointer<TView>,
|
||||||
|
ffi.Pointer<TScene>)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TGizmo> SceneManager_createGizmo(
|
||||||
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TScene> tScene,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
EntityId Function(
|
EntityId Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
@@ -658,6 +667,14 @@ external ffi.Pointer<TMaterialInstance>
|
|||||||
ffi.Pointer<TSceneManager> sceneManager,
|
ffi.Pointer<TSceneManager> sceneManager,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Pointer<TMaterialInstance> Function(
|
||||||
|
ffi.Pointer<TSceneManager>)>(isLeaf: true)
|
||||||
|
external ffi.Pointer<TMaterialInstance>
|
||||||
|
SceneManager_createUnlitFixedSizeMaterialInstance(
|
||||||
|
ffi.Pointer<TSceneManager> sceneManager,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId,
|
ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId,
|
||||||
ffi.Pointer<ffi.Double>)>(isLeaf: true)
|
ffi.Pointer<ffi.Double>)>(isLeaf: true)
|
||||||
@@ -1035,6 +1052,12 @@ external void set_priority(
|
|||||||
int priority,
|
int priority,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<Aabb3 Function(ffi.Pointer<TSceneManager>, EntityId)>(isLeaf: true)
|
||||||
|
external Aabb3 SceneManager_getRenderableBoundingBox(
|
||||||
|
ffi.Pointer<TSceneManager> sceneManager,
|
||||||
|
int entity,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
Aabb2 Function(
|
Aabb2 Function(
|
||||||
ffi.Pointer<TSceneManager>, ffi.Pointer<TView>, EntityId)>(isLeaf: true)
|
ffi.Pointer<TSceneManager>, ffi.Pointer<TView>, EntityId)>(isLeaf: true)
|
||||||
@@ -1196,6 +1219,18 @@ external void MaterialInstance_setDepthCulling(
|
|||||||
bool enabled,
|
bool enabled,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
|
||||||
|
ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true)
|
||||||
|
external void MaterialInstance_setParameterFloat4(
|
||||||
|
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||||
|
ffi.Pointer<ffi.Char> name,
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
double w,
|
||||||
|
double z,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
|
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
|
||||||
ffi.Double, ffi.Double)>(isLeaf: true)
|
ffi.Double, ffi.Double)>(isLeaf: true)
|
||||||
@@ -1206,6 +1241,24 @@ external void MaterialInstance_setParameterFloat2(
|
|||||||
double y,
|
double y,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
|
||||||
|
ffi.Double)>(isLeaf: true)
|
||||||
|
external void MaterialInstance_setParameterFloat(
|
||||||
|
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||||
|
ffi.Pointer<ffi.Char> name,
|
||||||
|
double value,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<TMaterialInstance>, ffi.Pointer<ffi.Char>,
|
||||||
|
ffi.Int)>(isLeaf: true)
|
||||||
|
external void MaterialInstance_setParameterInt(
|
||||||
|
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||||
|
ffi.Pointer<ffi.Char> name,
|
||||||
|
int value,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
|
@ffi.Native<TViewport Function(ffi.Pointer<TView>)>(isLeaf: true)
|
||||||
external TViewport View_getViewport(
|
external TViewport View_getViewport(
|
||||||
ffi.Pointer<TView> view,
|
ffi.Pointer<TView> view,
|
||||||
@@ -1608,6 +1661,20 @@ external void SceneManager_createUnlitMaterialInstanceRenderThread(
|
|||||||
callback,
|
callback,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TSceneManager>,
|
||||||
|
ffi.Pointer<
|
||||||
|
ffi.NativeFunction<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<TMaterialInstance>)>>)>(isLeaf: true)
|
||||||
|
external void SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(
|
||||||
|
ffi.Pointer<TSceneManager> sceneManager,
|
||||||
|
ffi.Pointer<
|
||||||
|
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterialInstance>)>>
|
||||||
|
callback,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
@@ -2028,15 +2095,6 @@ void Camera_setProjection(
|
|||||||
far,
|
far,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
|
||||||
ffi.Pointer<TGizmo> Function(ffi.Pointer<TEngine>, ffi.Pointer<TView>,
|
|
||||||
ffi.Pointer<TScene>)>(isLeaf: true)
|
|
||||||
external ffi.Pointer<TGizmo> Gizmo_new(
|
|
||||||
ffi.Pointer<TEngine> tEngine,
|
|
||||||
ffi.Pointer<TView> tView,
|
|
||||||
ffi.Pointer<TScene> tScene,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<TGizmo>, ffi.Uint32, ffi.Uint32,
|
ffi.Void Function(ffi.Pointer<TGizmo>, ffi.Uint32, ffi.Uint32,
|
||||||
GizmoPickCallback)>(isLeaf: true)
|
GizmoPickCallback)>(isLeaf: true)
|
||||||
@@ -2245,6 +2303,26 @@ final class Aabb2 extends ffi.Struct {
|
|||||||
external double maxY;
|
external double maxY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class Aabb3 extends ffi.Struct {
|
||||||
|
@ffi.Float()
|
||||||
|
external double centerX;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double centerY;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double centerZ;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double halfExtentX;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double halfExtentY;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double halfExtentZ;
|
||||||
|
}
|
||||||
|
|
||||||
final class ResourceBuffer extends ffi.Struct {
|
final class ResourceBuffer extends ffi.Struct {
|
||||||
external ffi.Pointer<ffi.Void> data;
|
external ffi.Pointer<ffi.Void> data;
|
||||||
|
|
||||||
|
|||||||
@@ -83,8 +83,15 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
this._sharedContext = sharedContext ?? nullptr;
|
this._sharedContext = sharedContext ?? nullptr;
|
||||||
|
|
||||||
_onPickResultCallable = NativeCallable<
|
_onPickResultCallable = NativeCallable<
|
||||||
Void Function(EntityId entityId, Int x, Int y,
|
Void Function(
|
||||||
Pointer<TView> view, Float depth, Float fragX, Float fragY, Float fragZ)>.listener(_onPickResult);
|
EntityId entityId,
|
||||||
|
Int x,
|
||||||
|
Int y,
|
||||||
|
Pointer<TView> view,
|
||||||
|
Float depth,
|
||||||
|
Float fragX,
|
||||||
|
Float fragY,
|
||||||
|
Float fragZ)>.listener(_onPickResult);
|
||||||
|
|
||||||
_initialize();
|
_initialize();
|
||||||
}
|
}
|
||||||
@@ -300,7 +307,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_disposing = true;
|
_disposing = true;
|
||||||
|
|
||||||
await setRendering(false);
|
await setRendering(false);
|
||||||
await clearEntities();
|
await clearEntities();
|
||||||
await clearLights();
|
await clearLights();
|
||||||
@@ -1509,17 +1516,38 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onPickResult(
|
void _onPickResult(
|
||||||
ThermionEntity entityId, int x, int y, Pointer<TView> viewPtr, double depth, double fragX, double fragY, double fragZ) async {
|
ThermionEntity entityId,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
Pointer<TView> viewPtr,
|
||||||
|
double depth,
|
||||||
|
double fragX,
|
||||||
|
double fragY,
|
||||||
|
double fragZ) async {
|
||||||
final view = FFIView(viewPtr, _viewer!);
|
final view = FFIView(viewPtr, _viewer!);
|
||||||
final viewport = await view.getViewport();
|
final viewport = await view.getViewport();
|
||||||
|
|
||||||
_pickResultController
|
_pickResultController.add((
|
||||||
.add((entity: entityId, x: x.ceil(), y: (viewport.height - y).ceil(), depth: depth, fragX: fragX, fragY: viewport.height - fragY, fragZ: fragZ ));
|
entity: entityId,
|
||||||
|
x: x,
|
||||||
|
y: (viewport.height - y),
|
||||||
|
depth: depth,
|
||||||
|
fragX: fragX,
|
||||||
|
fragY: viewport.height - fragY,
|
||||||
|
fragZ: fragZ
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
late NativeCallable<
|
late NativeCallable<
|
||||||
Void Function(EntityId entityId, Int x, Int y, Pointer<TView> view, Float depth, Float fragX, Float fragY, Float fragZ)>
|
Void Function(
|
||||||
_onPickResultCallable;
|
EntityId entityId,
|
||||||
|
Int x,
|
||||||
|
Int y,
|
||||||
|
Pointer<TView> view,
|
||||||
|
Float depth,
|
||||||
|
Float fragX,
|
||||||
|
Float fragY,
|
||||||
|
Float fragZ)> _onPickResultCallable;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -1528,7 +1556,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future pick(int x, int y) async {
|
Future pick(int x, int y) async {
|
||||||
final view = (await getViewAt(0)) as FFIView;
|
final view = (await getViewAt(0)) as FFIView;
|
||||||
var viewport = await view.getViewport();
|
var viewport = await view.getViewport();
|
||||||
y = (viewport.height - y).ceil();
|
y = viewport.height - y;
|
||||||
Viewer_pick(
|
Viewer_pick(
|
||||||
_viewer!, view.view, x, y, _onPickResultCallable.nativeFunction);
|
_viewer!, view.view, x, y, _onPickResultCallable.nativeFunction);
|
||||||
}
|
}
|
||||||
@@ -1750,6 +1778,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
throw Exception("Viewer must not be null");
|
throw Exception("Viewer must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var entity = await withIntCallback((callback) =>
|
var entity = await withIntCallback((callback) =>
|
||||||
SceneManager_createGeometryRenderThread(
|
SceneManager_createGeometryRenderThread(
|
||||||
_sceneManager!,
|
_sceneManager!,
|
||||||
@@ -1835,6 +1864,18 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
set_priority(_sceneManager!, entityId, priority);
|
set_priority(_sceneManager!, entityId, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
@override
|
||||||
|
Future<v64.Aabb3> getRenderableBoundingBox(ThermionEntity entityId) async {
|
||||||
|
final result =
|
||||||
|
SceneManager_getRenderableBoundingBox(_sceneManager!, entityId);
|
||||||
|
return v64.Aabb3.centerAndHalfExtents(
|
||||||
|
Vector3(result.centerX, result.centerY, result.centerZ),
|
||||||
|
Vector3(result.halfExtentX, result.halfExtentY, result.halfExtentZ));
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -2035,6 +2076,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
destroy_material_instance(_sceneManager!, materialInstance._pointer);
|
destroy_material_instance(_sceneManager!, materialInstance._pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
Future<ThermionFFIMaterialInstance> createUnlitMaterialInstance() async {
|
Future<ThermionFFIMaterialInstance> createUnlitMaterialInstance() async {
|
||||||
var instance = await withPointerCallback<TMaterialInstance>((cb) {
|
var instance = await withPointerCallback<TMaterialInstance>((cb) {
|
||||||
SceneManager_createUnlitMaterialInstanceRenderThread(_sceneManager!, cb);
|
SceneManager_createUnlitMaterialInstanceRenderThread(_sceneManager!, cb);
|
||||||
@@ -2045,6 +2089,21 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
return ThermionFFIMaterialInstance(instance);
|
return ThermionFFIMaterialInstance(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future<ThermionFFIMaterialInstance>
|
||||||
|
createUnlitFixedSizeMaterialInstance() async {
|
||||||
|
var instance = await withPointerCallback<TMaterialInstance>((cb) {
|
||||||
|
SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(
|
||||||
|
_sceneManager!, cb);
|
||||||
|
});
|
||||||
|
if (instance == nullptr) {
|
||||||
|
throw Exception("Failed to create material instance");
|
||||||
|
}
|
||||||
|
return ThermionFFIMaterialInstance(instance);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setMaterialPropertyInt(ThermionEntity entity, String propertyName,
|
Future setMaterialPropertyInt(ThermionEntity entity, String propertyName,
|
||||||
int materialIndex, int value) {
|
int materialIndex, int value) {
|
||||||
@@ -2163,7 +2222,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future<Gizmo> createGizmo(FFIView view) async {
|
Future<Gizmo> createGizmo(FFIView view) async {
|
||||||
var view = (await getViewAt(0)) as FFIView;
|
var view = (await getViewAt(0)) as FFIView;
|
||||||
var scene = View_getScene(view.view);
|
var scene = View_getScene(view.view);
|
||||||
final gizmo = Gizmo_new(Viewer_getEngine(_viewer!), view.view, scene);
|
final gizmo = SceneManager_createGizmo(_sceneManager!, view.view, scene);
|
||||||
return FFIGizmo(gizmo, this);
|
return FFIGizmo(gizmo, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2189,11 +2248,31 @@ class ThermionFFIMaterialInstance extends MaterialInstance {
|
|||||||
MaterialInstance_setDepthWrite(this._pointer, enabled);
|
MaterialInstance_setDepthWrite(this._pointer, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setParameterFloat4(String name, double x, double y, double z, double w) async {
|
||||||
|
MaterialInstance_setParameterFloat4(
|
||||||
|
_pointer, name.toNativeUtf8().cast<Char>(), x, y, z, w);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setParameterFloat2(String name, double x, double y) async {
|
Future setParameterFloat2(String name, double x, double y) async {
|
||||||
MaterialInstance_setParameterFloat2(
|
MaterialInstance_setParameterFloat2(
|
||||||
_pointer, name.toNativeUtf8().cast<Char>(), x, y);
|
_pointer, name.toNativeUtf8().cast<Char>(), x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setParameterFloat(String name, double value) async {
|
||||||
|
MaterialInstance_setParameterFloat(
|
||||||
|
_pointer, name.toNativeUtf8().cast<Char>(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setParameterInt(String name, int value) async {
|
||||||
|
MaterialInstance_setParameterInt(
|
||||||
|
_pointer, name.toNativeUtf8().cast<Char>(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FFIRenderTarget extends RenderTarget {
|
class FFIRenderTarget extends RenderTarget {
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
abstract class MaterialInstance {
|
abstract class MaterialInstance {
|
||||||
Future setDepthWriteEnabled(bool enabled);
|
Future setDepthWriteEnabled(bool enabled);
|
||||||
|
|
||||||
Future setDepthCullingEnabled(bool enabled);
|
Future setDepthCullingEnabled(bool enabled);
|
||||||
|
Future setParameterFloat4(String name, double x, double y, double z, double w);
|
||||||
Future setParameterFloat2(String name, double x, double y);
|
Future setParameterFloat2(String name, double x, double y);
|
||||||
|
Future setParameterFloat(String name, double x);
|
||||||
|
Future setParameterInt(String name, int value);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AlphaMode { OPAQUE, MASK, BLEND }
|
enum AlphaMode { OPAQUE, MASK, BLEND }
|
||||||
|
|||||||
@@ -790,6 +790,11 @@ abstract class ThermionViewer {
|
|||||||
///
|
///
|
||||||
void onDispose(Future Function() callback);
|
void onDispose(Future Function() callback);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets the 3D axis aligned bounding box for the given entity.
|
||||||
|
///
|
||||||
|
Future<Aabb3> getRenderableBoundingBox(ThermionEntity entity);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Gets the 2D bounding box (in viewport coordinates) for the given entity.
|
/// Gets the 2D bounding box (in viewport coordinates) for the given entity.
|
||||||
///
|
///
|
||||||
@@ -895,6 +900,11 @@ abstract class ThermionViewer {
|
|||||||
///
|
///
|
||||||
Future<MaterialInstance> createUnlitMaterialInstance();
|
Future<MaterialInstance> createUnlitMaterialInstance();
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future<MaterialInstance> createUnlitFixedSizeMaterialInstance();
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -21,4 +21,10 @@ class ThermionWasmMaterialInstance extends MaterialInstance {
|
|||||||
// TODO: implement setParameterFloat2
|
// TODO: implement setParameterFloat2
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future setParameterFloat(String name, double x) {
|
||||||
|
// TODO: implement setParameterFloat
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,17 @@ extern "C"
|
|||||||
|
|
||||||
typedef struct Aabb2 Aabb2;
|
typedef struct Aabb2 Aabb2;
|
||||||
|
|
||||||
|
struct Aabb3 {
|
||||||
|
float centerX;
|
||||||
|
float centerY;
|
||||||
|
float centerZ;
|
||||||
|
float halfExtentX;
|
||||||
|
float halfExtentY;
|
||||||
|
float halfExtentZ;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Aabb3 Aabb3;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3,13 +3,16 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
|
#include <filament/Frustum.h>
|
||||||
#include <filament/VertexBuffer.h>
|
#include <filament/VertexBuffer.h>
|
||||||
#include <filament/IndexBuffer.h>
|
#include <filament/IndexBuffer.h>
|
||||||
#include <filament/TransformManager.h>
|
#include <filament/TransformManager.h>
|
||||||
#include <filament/Texture.h>
|
#include <filament/Texture.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
#include <filament/Viewport.h>
|
#include <filament/Viewport.h>
|
||||||
#include <filament/Frustum.h>
|
|
||||||
|
#include <utils/Entity.h>
|
||||||
|
#include <utils/EntityManager.h>
|
||||||
|
|
||||||
namespace thermion
|
namespace thermion
|
||||||
{
|
{
|
||||||
@@ -32,9 +35,13 @@ public:
|
|||||||
Engine* engine);
|
Engine* engine);
|
||||||
~CustomGeometry();
|
~CustomGeometry();
|
||||||
|
|
||||||
VertexBuffer* vertexBuffer() const;
|
utils::Entity createInstance(MaterialInstance *materialInstance);
|
||||||
IndexBuffer* indexBuffer() const;
|
|
||||||
Box getBoundingBox() const;
|
private:
|
||||||
|
Engine* _engine;
|
||||||
|
|
||||||
|
VertexBuffer* vertexBuffer;
|
||||||
|
IndexBuffer* indexBuffer;
|
||||||
|
|
||||||
float* vertices = nullptr;
|
float* vertices = nullptr;
|
||||||
float* normals = nullptr;
|
float* normals = nullptr;
|
||||||
@@ -45,11 +52,6 @@ public:
|
|||||||
Box boundingBox;
|
Box boundingBox;
|
||||||
RenderableManager::PrimitiveType primitiveType;
|
RenderableManager::PrimitiveType primitiveType;
|
||||||
|
|
||||||
private:
|
|
||||||
Engine* _engine;
|
|
||||||
bool _vertexBufferFreed = false;
|
|
||||||
bool _indexBufferFreed = false;
|
|
||||||
|
|
||||||
void computeBoundingBox();
|
void computeBoundingBox();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
#include <filament/IndexBuffer.h>
|
#include <filament/IndexBuffer.h>
|
||||||
#include <filament/InstanceBuffer.h>
|
#include <filament/InstanceBuffer.h>
|
||||||
|
|
||||||
#include "material/gizmo.h"
|
|
||||||
|
|
||||||
#include "ThermionDartApi.h"
|
#include "ThermionDartApi.h"
|
||||||
|
|
||||||
namespace thermion {
|
namespace thermion {
|
||||||
@@ -31,7 +29,7 @@ class Gizmo {
|
|||||||
enum Axis { X, Y, Z};
|
enum Axis { X, Y, Z};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gizmo(Engine *engine, View *view, Scene *scene);
|
Gizmo(Engine *engine, View *view, Scene *scene, Material* material);
|
||||||
~Gizmo();
|
~Gizmo();
|
||||||
|
|
||||||
typedef void (*PickCallback)(EntityId entityId, uint32_t x, uint32_t y, View *view);
|
typedef void (*PickCallback)(EntityId entityId, uint32_t x, uint32_t y, View *view);
|
||||||
@@ -91,8 +89,10 @@ class Gizmo {
|
|||||||
Engine *_engine;
|
Engine *_engine;
|
||||||
Scene *_scene;
|
Scene *_scene;
|
||||||
View *_view;
|
View *_view;
|
||||||
utils::Entity _entities[7] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
|
|
||||||
Material* _material;
|
Material* _material;
|
||||||
|
|
||||||
|
utils::Entity _entities[7] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
|
||||||
|
|
||||||
MaterialInstance* _materialInstances[7];
|
MaterialInstance* _materialInstances[7];
|
||||||
math::float4 inactiveColors[3] {
|
math::float4 inactiveColors[3] {
|
||||||
math::float4 { 1.0f, 0.0f, 0.0f, 0.5f },
|
math::float4 { 1.0f, 0.0f, 0.0f, 0.5f },
|
||||||
|
|||||||
@@ -19,9 +19,6 @@
|
|||||||
#include <filament/IndexBuffer.h>
|
#include <filament/IndexBuffer.h>
|
||||||
#include <filament/InstanceBuffer.h>
|
#include <filament/InstanceBuffer.h>
|
||||||
|
|
||||||
#include "material/gizmo.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace thermion {
|
namespace thermion {
|
||||||
|
|
||||||
using namespace filament;
|
using namespace filament;
|
||||||
|
|||||||
@@ -19,16 +19,17 @@
|
|||||||
#include <filament/InstanceBuffer.h>
|
#include <filament/InstanceBuffer.h>
|
||||||
#include <utils/NameComponentManager.h>
|
#include <utils/NameComponentManager.h>
|
||||||
|
|
||||||
#include "CustomGeometry.hpp"
|
#include "tsl/robin_map.h"
|
||||||
|
|
||||||
|
|
||||||
#include "APIBoundaryTypes.h"
|
#include "APIBoundaryTypes.h"
|
||||||
|
#include "CustomGeometry.hpp"
|
||||||
|
#include "Gizmo.hpp"
|
||||||
#include "GridOverlay.hpp"
|
#include "GridOverlay.hpp"
|
||||||
#include "ResourceBuffer.hpp"
|
#include "ResourceBuffer.hpp"
|
||||||
#include "components/CollisionComponentManager.hpp"
|
#include "components/CollisionComponentManager.hpp"
|
||||||
#include "components/AnimationComponentManager.hpp"
|
#include "components/AnimationComponentManager.hpp"
|
||||||
|
|
||||||
#include "tsl/robin_map.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace thermion
|
namespace thermion
|
||||||
{
|
{
|
||||||
@@ -229,7 +230,12 @@ namespace thermion
|
|||||||
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
|
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
|
||||||
/// @return
|
/// @return
|
||||||
///
|
///
|
||||||
Aabb2 getBoundingBox(View* view, EntityId entity);
|
Aabb2 getScreenSpaceBoundingBox(View* view, EntityId entity);
|
||||||
|
|
||||||
|
/// @brief returns the 3D bounding box of the renderable instance for the given entity.
|
||||||
|
/// @return the bounding box
|
||||||
|
///
|
||||||
|
Aabb3 getRenderableBoundingBox(EntityId entity);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Creates an entity with the specified geometry/material/normals and adds to the scene.
|
/// Creates an entity with the specified geometry/material/normals and adds to the scene.
|
||||||
@@ -255,11 +261,15 @@ namespace thermion
|
|||||||
return _unlitMaterialProvider;
|
return _unlitMaterialProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isGeometryInstance(EntityId entity) {
|
||||||
|
return std::find(_geometryInstances.begin(), _geometryInstances.end(), entity) != _geometryInstances.end();
|
||||||
|
}
|
||||||
|
|
||||||
bool isGeometryEntity(EntityId entity) {
|
bool isGeometryEntity(EntityId entity) {
|
||||||
return _geometry.find(entity) != _geometry.end();
|
return _geometry.find(entity) != _geometry.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomGeometry* const getGeometry(EntityId entityId) {
|
CustomGeometry* const getGeometry(EntityId entityId) {
|
||||||
return _geometry[entityId].get();
|
return _geometry[entityId].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +297,8 @@ namespace thermion
|
|||||||
return _ubershaderProvider;
|
return _ubershaderProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialInstance* createUnlitFixedSizeMaterialInstance();
|
||||||
|
|
||||||
MaterialInstance* createUnlitMaterialInstance();
|
MaterialInstance* createUnlitMaterialInstance();
|
||||||
|
|
||||||
void setVisibilityLayer(EntityId entityId, int layer);
|
void setVisibilityLayer(EntityId entityId, int layer);
|
||||||
@@ -298,6 +310,8 @@ namespace thermion
|
|||||||
size_t getCameraCount();
|
size_t getCameraCount();
|
||||||
|
|
||||||
Camera* getCameraAt(size_t index);
|
Camera* getCameraAt(size_t index);
|
||||||
|
|
||||||
|
Gizmo *createGizmo(View *view, Scene *scene);
|
||||||
|
|
||||||
bool isGizmoEntity(utils::Entity entity);
|
bool isGizmoEntity(utils::Entity entity);
|
||||||
|
|
||||||
@@ -321,6 +335,8 @@ namespace thermion
|
|||||||
std::mutex _stencilMutex;
|
std::mutex _stencilMutex;
|
||||||
std::vector<MaterialInstance*> _materialInstances;
|
std::vector<MaterialInstance*> _materialInstances;
|
||||||
|
|
||||||
|
Material* _gizmoMaterial = nullptr;
|
||||||
|
|
||||||
utils::NameComponentManager *_ncm;
|
utils::NameComponentManager *_ncm;
|
||||||
|
|
||||||
tsl::robin_map<
|
tsl::robin_map<
|
||||||
@@ -329,6 +345,7 @@ namespace thermion
|
|||||||
_instances;
|
_instances;
|
||||||
tsl::robin_map<EntityId, gltfio::FilamentAsset *> _assets;
|
tsl::robin_map<EntityId, gltfio::FilamentAsset *> _assets;
|
||||||
tsl::robin_map<EntityId, unique_ptr<CustomGeometry>> _geometry;
|
tsl::robin_map<EntityId, unique_ptr<CustomGeometry>> _geometry;
|
||||||
|
std::vector<EntityId> _geometryInstances;
|
||||||
tsl::robin_map<EntityId, unique_ptr<HighlightOverlay>> _highlighted;
|
tsl::robin_map<EntityId, unique_ptr<HighlightOverlay>> _highlighted;
|
||||||
tsl::robin_map<EntityId, math::mat4> _transformUpdates;
|
tsl::robin_map<EntityId, math::mat4> _transformUpdates;
|
||||||
std::set<Texture*> _textures;
|
std::set<Texture*> _textures;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ extern "C"
|
|||||||
|
|
||||||
typedef void (*GizmoPickCallback)(EntityId entityId, uint32_t x, uint32_t y, TView* view);
|
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_pick(TGizmo *tGizmo, uint32_t x, uint32_t y, GizmoPickCallback callback);
|
||||||
EMSCRIPTEN_KEEPALIVE void Gizmo_setVisibility(TGizmo *tGizmo, bool visible);
|
EMSCRIPTEN_KEEPALIVE void Gizmo_setVisibility(TGizmo *tGizmo, bool visible);
|
||||||
|
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ extern "C"
|
|||||||
int skinIndex,
|
int skinIndex,
|
||||||
int boneIndex);
|
int boneIndex);
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TGizmo* SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_createGeometry(
|
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_createGeometry(
|
||||||
TSceneManager *sceneManager,
|
TSceneManager *sceneManager,
|
||||||
float *vertices,
|
float *vertices,
|
||||||
@@ -212,6 +213,7 @@ extern "C"
|
|||||||
TMaterialInstance *materialInstance,
|
TMaterialInstance *materialInstance,
|
||||||
bool keepData);
|
bool keepData);
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitMaterialInstance(TSceneManager *sceneManager);
|
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitMaterialInstance(TSceneManager *sceneManager);
|
||||||
|
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitFixedSizeMaterialInstance(TSceneManager *sceneManager);
|
||||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_setTransform(TSceneManager *sceneManager, EntityId entityId, const double *const transform);
|
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 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 TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name);
|
||||||
@@ -275,6 +277,7 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE void test_collisions(TSceneManager *sceneManager, EntityId entity);
|
EMSCRIPTEN_KEEPALIVE void test_collisions(TSceneManager *sceneManager, EntityId entity);
|
||||||
EMSCRIPTEN_KEEPALIVE void set_priority(TSceneManager *sceneManager, EntityId entityId, int priority);
|
EMSCRIPTEN_KEEPALIVE void set_priority(TSceneManager *sceneManager, EntityId entityId, int priority);
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb3 SceneManager_getRenderableBoundingBox(TSceneManager *sceneManager, EntityId entity);
|
||||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *view, EntityId entity);
|
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 get_bounding_box_to_out(TSceneManager *sceneManager, TView *view, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
|
||||||
|
|
||||||
@@ -294,7 +297,10 @@ extern "C"
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled);
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled);
|
||||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled);
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance* materialInstance, const char* name, double x, double y, double w, double z);
|
||||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y);
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance* materialInstance, const char* name, double value);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance* materialInstance, const char* name, int value);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ extern "C"
|
|||||||
void (*callback)(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 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 SceneManager_createUnlitMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance*));
|
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance*));
|
||||||
|
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance*));
|
||||||
EMSCRIPTEN_KEEPALIVE void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, 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 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 create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
.global GIZMO_GIZMO_OFFSET;
|
|
||||||
.global GIZMO_GIZMO_SIZE;
|
|
||||||
|
|
||||||
.global GIZMO_PACKAGE
|
|
||||||
.section .rodata
|
|
||||||
GIZMO_PACKAGE:
|
|
||||||
.incbin "gizmo.bin"
|
|
||||||
GIZMO_GIZMO_OFFSET:
|
|
||||||
.int 0
|
|
||||||
GIZMO_GIZMO_SIZE:
|
|
||||||
.int 27809
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
.global _GIZMO_GIZMO_OFFSET;
|
|
||||||
.global _GIZMO_GIZMO_SIZE;
|
|
||||||
|
|
||||||
.global _GIZMO_PACKAGE
|
|
||||||
.section __TEXT,__const
|
|
||||||
_GIZMO_PACKAGE:
|
|
||||||
.incbin "gizmo.bin"
|
|
||||||
_GIZMO_GIZMO_OFFSET:
|
|
||||||
.int 0
|
|
||||||
_GIZMO_GIZMO_SIZE:
|
|
||||||
.int 27809
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -1,13 +0,0 @@
|
|||||||
#ifndef GIZMO_H_
|
|
||||||
#define GIZMO_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
extern const uint8_t GIZMO_PACKAGE[];
|
|
||||||
extern int GIZMO_GIZMO_OFFSET;
|
|
||||||
extern int GIZMO_GIZMO_SIZE;
|
|
||||||
}
|
|
||||||
#define GIZMO_GIZMO_DATA (GIZMO_PACKAGE + GIZMO_GIZMO_OFFSET)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
12
thermion_dart/native/include/material/unlit_fixed_size.S
Normal file
12
thermion_dart/native/include/material/unlit_fixed_size.S
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.global UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET;
|
||||||
|
.global UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE;
|
||||||
|
|
||||||
|
.global UNLIT_FIXED_SIZE_PACKAGE
|
||||||
|
.section .rodata
|
||||||
|
UNLIT_FIXED_SIZE_PACKAGE:
|
||||||
|
.incbin "unlit_fixed_size.bin"
|
||||||
|
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
|
||||||
|
.int 0
|
||||||
|
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
|
||||||
|
.int 28235
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
.global _UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET;
|
||||||
|
.global _UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE;
|
||||||
|
|
||||||
|
.global _UNLIT_FIXED_SIZE_PACKAGE
|
||||||
|
.section __TEXT,__const
|
||||||
|
_UNLIT_FIXED_SIZE_PACKAGE:
|
||||||
|
.incbin "unlit_fixed_size.bin"
|
||||||
|
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
|
||||||
|
.int 0
|
||||||
|
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
|
||||||
|
.int 28235
|
||||||
|
|
||||||
BIN
thermion_dart/native/include/material/unlit_fixed_size.bin
Normal file
BIN
thermion_dart/native/include/material/unlit_fixed_size.bin
Normal file
Binary file not shown.
1422
thermion_dart/native/include/material/unlit_fixed_size.c
Normal file
1422
thermion_dart/native/include/material/unlit_fixed_size.c
Normal file
File diff suppressed because it is too large
Load Diff
13
thermion_dart/native/include/material/unlit_fixed_size.h
Normal file
13
thermion_dart/native/include/material/unlit_fixed_size.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef UNLIT_FIXED_SIZE_H_
|
||||||
|
#define UNLIT_FIXED_SIZE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern const uint8_t UNLIT_FIXED_SIZE_PACKAGE[];
|
||||||
|
extern int UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET;
|
||||||
|
extern int UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE;
|
||||||
|
}
|
||||||
|
#define UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_DATA (UNLIT_FIXED_SIZE_PACKAGE + UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/Frustum.h>
|
#include <filament/Frustum.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
@@ -6,207 +9,232 @@
|
|||||||
#include <filament/TransformManager.h>
|
#include <filament/TransformManager.h>
|
||||||
#include <filament/Viewport.h>
|
#include <filament/Viewport.h>
|
||||||
#include <filament/geometry/SurfaceOrientation.h>
|
#include <filament/geometry/SurfaceOrientation.h>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "CustomGeometry.hpp"
|
#include "CustomGeometry.hpp"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
|
||||||
|
namespace thermion
|
||||||
|
{
|
||||||
|
|
||||||
namespace thermion {
|
using namespace filament;
|
||||||
|
|
||||||
using namespace filament;
|
CustomGeometry::CustomGeometry(float *vertices, uint32_t numVertices,
|
||||||
|
float *normals, uint32_t numNormals, float *uvs,
|
||||||
|
uint32_t numUvs, uint16_t *indices,
|
||||||
|
uint32_t numIndices,
|
||||||
|
RenderableManager::PrimitiveType primitiveType,
|
||||||
|
Engine *engine)
|
||||||
|
: numVertices(numVertices), numIndices(numIndices), _engine(engine)
|
||||||
|
{
|
||||||
|
|
||||||
CustomGeometry::CustomGeometry(float *vertices, uint32_t numVertices,
|
this->primitiveType = primitiveType;
|
||||||
float *normals, uint32_t numNormals, float *uvs,
|
this->vertices = new float[numVertices];
|
||||||
uint32_t numUvs, uint16_t *indices,
|
|
||||||
uint32_t numIndices,
|
|
||||||
RenderableManager::PrimitiveType primitiveType,
|
|
||||||
Engine *engine)
|
|
||||||
: numVertices(numVertices), numIndices(numIndices), _engine(engine) {
|
|
||||||
this->primitiveType = primitiveType;
|
|
||||||
this->vertices = new float[numVertices];
|
|
||||||
std::memcpy(this->vertices, vertices, numVertices * sizeof(float));
|
|
||||||
|
|
||||||
if (numNormals > 0) {
|
std::memcpy(this->vertices, vertices, numVertices * sizeof(float));
|
||||||
this->normals = new float[numNormals];
|
|
||||||
std::memcpy(this->normals, normals, numNormals * sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numUvs > 0) {
|
if (numNormals > 0)
|
||||||
this->uvs = new float[numUvs];
|
{
|
||||||
std::memcpy(this->uvs, uvs, numUvs * sizeof(float));
|
this->normals = new float[numNormals];
|
||||||
} else {
|
std::memcpy(this->normals, normals, numNormals * sizeof(float));
|
||||||
this->uvs = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->indices = new uint16_t[numIndices];
|
|
||||||
std::memcpy(this->indices, indices, numIndices * sizeof(uint16_t));
|
|
||||||
|
|
||||||
computeBoundingBox();
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexBuffer *CustomGeometry::indexBuffer() const {
|
|
||||||
IndexBuffer::BufferDescriptor::Callback indexCallback = [](void *buf, size_t,
|
|
||||||
void *data) {
|
|
||||||
// free((void *)buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto indexBuffer = IndexBuffer::Builder()
|
|
||||||
.indexCount(numIndices)
|
|
||||||
.bufferType(IndexBuffer::IndexType::USHORT)
|
|
||||||
.build(*_engine);
|
|
||||||
|
|
||||||
indexBuffer->setBuffer(*_engine,
|
|
||||||
IndexBuffer::BufferDescriptor(
|
|
||||||
this->indices,
|
|
||||||
indexBuffer->getIndexCount() * sizeof(uint16_t),
|
|
||||||
indexCallback));
|
|
||||||
return indexBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexBuffer *CustomGeometry::vertexBuffer() const {
|
|
||||||
VertexBuffer::BufferDescriptor::Callback vertexCallback =
|
|
||||||
[](void *buf, size_t, void *data) {
|
|
||||||
// free((void *)buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use provided UVs or create dummy UV data
|
|
||||||
std::vector<filament::math::float2> *uvData;
|
|
||||||
if (this->uvs != nullptr) {
|
|
||||||
uvData = new std::vector<filament::math::float2>(
|
|
||||||
(filament::math::float2 *)this->uvs,
|
|
||||||
(filament::math::float2 *)(this->uvs + numVertices * 2));
|
|
||||||
} else {
|
|
||||||
uvData = new std::vector<filament::math::float2>(
|
|
||||||
numVertices, filament::math::float2{0.0f, 0.0f});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create dummy vertex color data (white color for all vertices)
|
|
||||||
auto dummyColors = new std::vector<filament::math::float4>(
|
|
||||||
numVertices, filament::math::float4{1.0f, 1.0f, 1.0f, 1.0f});
|
|
||||||
|
|
||||||
auto vertexBufferBuilder =
|
|
||||||
VertexBuffer::Builder()
|
|
||||||
.vertexCount(numVertices)
|
|
||||||
.attribute(VertexAttribute::POSITION, 0,
|
|
||||||
VertexBuffer::AttributeType::FLOAT3)
|
|
||||||
.attribute(VertexAttribute::UV0, 1,
|
|
||||||
VertexBuffer::AttributeType::FLOAT2)
|
|
||||||
.attribute(VertexAttribute::UV1, 2,
|
|
||||||
VertexBuffer::AttributeType::FLOAT2)
|
|
||||||
.attribute(VertexAttribute::COLOR, 3,
|
|
||||||
VertexBuffer::AttributeType::FLOAT4);
|
|
||||||
|
|
||||||
if (this->normals) {
|
|
||||||
vertexBufferBuilder.bufferCount(5).attribute(
|
|
||||||
VertexAttribute::TANGENTS, 4,
|
|
||||||
filament::VertexBuffer::AttributeType::FLOAT4);
|
|
||||||
} else {
|
|
||||||
vertexBufferBuilder = vertexBufferBuilder.bufferCount(4);
|
|
||||||
}
|
|
||||||
auto vertexBuffer = vertexBufferBuilder.build(*_engine);
|
|
||||||
|
|
||||||
vertexBuffer->setBufferAt(
|
|
||||||
*_engine, 0,
|
|
||||||
VertexBuffer::BufferDescriptor(
|
|
||||||
this->vertices, vertexBuffer->getVertexCount() * sizeof(math::float3),
|
|
||||||
vertexCallback));
|
|
||||||
|
|
||||||
// Set UV0 buffer
|
|
||||||
vertexBuffer->setBufferAt(
|
|
||||||
*_engine, 1,
|
|
||||||
VertexBuffer::BufferDescriptor(
|
|
||||||
uvData->data(), uvData->size() * sizeof(math::float2),
|
|
||||||
[](void *buf, size_t, void *data) {
|
|
||||||
delete static_cast<std::vector<math::float2> *>(data);
|
|
||||||
},
|
|
||||||
uvData));
|
|
||||||
|
|
||||||
// Set UV1 buffer (reusing UV0 data)
|
|
||||||
vertexBuffer->setBufferAt(*_engine, 2,
|
|
||||||
VertexBuffer::BufferDescriptor(
|
|
||||||
uvData->data(),
|
|
||||||
uvData->size() * sizeof(math::float2),
|
|
||||||
[](void *buf, size_t, void *data) {
|
|
||||||
// Do nothing here, as we're reusing the same
|
|
||||||
// data as UV0
|
|
||||||
},
|
|
||||||
nullptr));
|
|
||||||
|
|
||||||
// Set vertex color buffer
|
|
||||||
vertexBuffer->setBufferAt(
|
|
||||||
*_engine, 3,
|
|
||||||
VertexBuffer::BufferDescriptor(
|
|
||||||
dummyColors->data(), dummyColors->size() * sizeof(math::float4),
|
|
||||||
[](void *buf, size_t, void *data) {
|
|
||||||
delete static_cast<std::vector<math::float4> *>(data);
|
|
||||||
},
|
|
||||||
dummyColors));
|
|
||||||
|
|
||||||
if (this->normals) {
|
|
||||||
|
|
||||||
assert(this->primitiveType == RenderableManager::PrimitiveType::TRIANGLES);
|
|
||||||
std::vector<filament::math::ushort3> triangles;
|
|
||||||
for (int i = 0; i < numIndices; i += 3) {
|
|
||||||
filament::math::ushort3 triangle;
|
|
||||||
triangle.x = this->indices[i];
|
|
||||||
triangle.y = this->indices[i + 1];
|
|
||||||
triangle.z = this->indices[i + 2];
|
|
||||||
triangles.push_back(triangle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a SurfaceOrientation builder
|
if (numUvs > 0)
|
||||||
geometry::SurfaceOrientation::Builder builder;
|
{
|
||||||
builder.vertexCount(numVertices)
|
this->uvs = new float[numUvs];
|
||||||
.normals((filament::math::float3 *)normals)
|
std::memcpy(this->uvs, uvs, numUvs * sizeof(float));
|
||||||
.positions((filament::math::float3 *)this->vertices)
|
}
|
||||||
.triangleCount(triangles.size())
|
else
|
||||||
.triangles(triangles.data());
|
{
|
||||||
|
this->uvs = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Build the SurfaceOrientation object
|
this->indices = new uint16_t[numIndices];
|
||||||
auto orientation = builder.build();
|
|
||||||
|
|
||||||
// Retrieve the quaternions
|
std::memcpy(this->indices, indices, numIndices * sizeof(uint16_t));
|
||||||
auto quats = new std::vector<filament::math::quatf>(numVertices);
|
|
||||||
orientation->getQuats(quats->data(), numVertices);
|
|
||||||
|
|
||||||
vertexBuffer->setBufferAt(*_engine, 4,
|
computeBoundingBox();
|
||||||
|
|
||||||
|
indexBuffer = IndexBuffer::Builder()
|
||||||
|
.indexCount(numIndices)
|
||||||
|
.bufferType(IndexBuffer::IndexType::USHORT)
|
||||||
|
.build(*_engine);
|
||||||
|
|
||||||
|
indexBuffer->setBuffer(*_engine,
|
||||||
|
IndexBuffer::BufferDescriptor(
|
||||||
|
this->indices,
|
||||||
|
indexBuffer->getIndexCount() * sizeof(uint16_t),
|
||||||
|
[](void *buf, size_t,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
free((void *)buf);
|
||||||
|
}));
|
||||||
|
|
||||||
|
std::vector<filament::math::float2> *uvData;
|
||||||
|
if (this->uvs != nullptr)
|
||||||
|
{
|
||||||
|
uvData = new std::vector<filament::math::float2>(
|
||||||
|
(filament::math::float2 *)this->uvs,
|
||||||
|
(filament::math::float2 *)(this->uvs + numVertices * 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uvData = new std::vector<filament::math::float2>(
|
||||||
|
numVertices, filament::math::float2{0.0f, 0.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create dummy vertex color data (white color for all vertices)
|
||||||
|
auto dummyColors = new std::vector<filament::math::float4>(
|
||||||
|
numVertices, filament::math::float4{1.0f, 1.0f, 1.0f, 1.0f});
|
||||||
|
|
||||||
|
auto vertexBufferBuilder =
|
||||||
|
VertexBuffer::Builder()
|
||||||
|
.vertexCount(numVertices)
|
||||||
|
.attribute(VertexAttribute::POSITION, 0,
|
||||||
|
VertexBuffer::AttributeType::FLOAT3)
|
||||||
|
.attribute(VertexAttribute::UV0, 1,
|
||||||
|
VertexBuffer::AttributeType::FLOAT2)
|
||||||
|
.attribute(VertexAttribute::UV1, 2,
|
||||||
|
VertexBuffer::AttributeType::FLOAT2)
|
||||||
|
.attribute(VertexAttribute::COLOR, 3,
|
||||||
|
VertexBuffer::AttributeType::FLOAT4);
|
||||||
|
|
||||||
|
if (this->normals)
|
||||||
|
{
|
||||||
|
vertexBufferBuilder.bufferCount(5).attribute(
|
||||||
|
VertexAttribute::TANGENTS, 4,
|
||||||
|
filament::VertexBuffer::AttributeType::FLOAT4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertexBufferBuilder = vertexBufferBuilder.bufferCount(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexBuffer = vertexBufferBuilder.build(*_engine);
|
||||||
|
|
||||||
|
vertexBuffer->setBufferAt(
|
||||||
|
*_engine, 0,
|
||||||
|
VertexBuffer::BufferDescriptor(
|
||||||
|
this->vertices, numVertices * sizeof(math::float3),
|
||||||
|
[](void *buf, size_t, void *data)
|
||||||
|
{
|
||||||
|
free((void *)buf);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Set UV0 buffer
|
||||||
|
vertexBuffer->setBufferAt(
|
||||||
|
*_engine, 1,
|
||||||
|
VertexBuffer::BufferDescriptor(
|
||||||
|
uvData->data(), uvData->size() * sizeof(math::float2),
|
||||||
|
[](void *buf, size_t, void *data)
|
||||||
|
{
|
||||||
|
delete static_cast<std::vector<math::float2> *>(data);
|
||||||
|
},
|
||||||
|
uvData));
|
||||||
|
|
||||||
|
// Set UV1 buffer (reusing UV0 data)
|
||||||
|
vertexBuffer->setBufferAt(*_engine, 2,
|
||||||
VertexBuffer::BufferDescriptor(
|
VertexBuffer::BufferDescriptor(
|
||||||
quats->data(),
|
uvData->data(),
|
||||||
quats->size() * sizeof(math::quatf),
|
uvData->size() * sizeof(math::float2),
|
||||||
[](void *buf, size_t, void *data) {
|
[](void *buf, size_t, void *data)
|
||||||
delete (std::vector<math::quatf> *)data;
|
{
|
||||||
|
// Do nothing here, as we're reusing the same
|
||||||
|
// data as UV0
|
||||||
},
|
},
|
||||||
(void *)quats));
|
nullptr));
|
||||||
}
|
|
||||||
return vertexBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomGeometry::~CustomGeometry() {
|
// Set vertex color buffer
|
||||||
delete[] vertices;
|
vertexBuffer->setBufferAt(
|
||||||
delete[] indices;
|
*_engine, 3,
|
||||||
if (normals)
|
VertexBuffer::BufferDescriptor(
|
||||||
delete[] normals;
|
dummyColors->data(), dummyColors->size() * sizeof(math::float4),
|
||||||
if (uvs)
|
[](void *buf, size_t, void *data)
|
||||||
delete[] uvs;
|
{
|
||||||
}
|
delete static_cast<std::vector<math::float4> *>(data);
|
||||||
|
},
|
||||||
|
dummyColors));
|
||||||
|
|
||||||
void CustomGeometry::computeBoundingBox() {
|
if (this->normals)
|
||||||
float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX;
|
{
|
||||||
float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < numVertices; i += 3) {
|
assert(this->primitiveType == RenderableManager::PrimitiveType::TRIANGLES);
|
||||||
minX = std::min(vertices[i], minX);
|
std::vector<filament::math::ushort3> triangles;
|
||||||
minY = std::min(vertices[i + 1], minY);
|
for (int i = 0; i < numIndices; i += 3)
|
||||||
minZ = std::min(vertices[i + 2], minZ);
|
{
|
||||||
maxX = std::max(vertices[i], maxX);
|
filament::math::ushort3 triangle;
|
||||||
maxY = std::max(vertices[i + 1], maxY);
|
triangle.x = this->indices[i];
|
||||||
maxZ = std::max(vertices[i + 2], maxZ);
|
triangle.y = this->indices[i + 1];
|
||||||
|
triangle.z = this->indices[i + 2];
|
||||||
|
triangles.push_back(triangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a SurfaceOrientation builder
|
||||||
|
geometry::SurfaceOrientation::Builder builder;
|
||||||
|
builder.vertexCount(numVertices)
|
||||||
|
.normals((filament::math::float3 *)normals)
|
||||||
|
.positions((filament::math::float3 *)this->vertices)
|
||||||
|
.triangleCount(triangles.size())
|
||||||
|
.triangles(triangles.data());
|
||||||
|
|
||||||
|
// Build the SurfaceOrientation object
|
||||||
|
auto orientation = builder.build();
|
||||||
|
|
||||||
|
// Retrieve the quaternions
|
||||||
|
auto quats = new std::vector<filament::math::quatf>(numVertices);
|
||||||
|
orientation->getQuats(quats->data(), numVertices);
|
||||||
|
|
||||||
|
vertexBuffer->setBufferAt(*_engine, 4,
|
||||||
|
VertexBuffer::BufferDescriptor(
|
||||||
|
quats->data(),
|
||||||
|
quats->size() * sizeof(math::quatf),
|
||||||
|
[](void *buf, size_t, void *data)
|
||||||
|
{
|
||||||
|
delete (std::vector<math::quatf> *)data;
|
||||||
|
},
|
||||||
|
(void *)quats));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boundingBox = Box{{minX, minY, minZ}, {maxX, maxY, maxZ}};
|
utils::Entity CustomGeometry::createInstance(MaterialInstance *materialInstance) {
|
||||||
}
|
auto entity = utils::EntityManager::get().create();
|
||||||
|
RenderableManager::Builder builder(1);
|
||||||
|
|
||||||
Box CustomGeometry::getBoundingBox() const { return boundingBox; }
|
builder.boundingBox(boundingBox)
|
||||||
|
.geometry(0, primitiveType, vertexBuffer, indexBuffer, 0, numIndices)
|
||||||
|
.culling(true)
|
||||||
|
.receiveShadows(true)
|
||||||
|
.castShadows(true);
|
||||||
|
|
||||||
|
builder.material(0, materialInstance);
|
||||||
|
builder.build(*_engine, entity);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomGeometry::~CustomGeometry()
|
||||||
|
{
|
||||||
|
Log("GEOMETRY DESTRUCTOR");
|
||||||
|
_engine->destroy(vertexBuffer);
|
||||||
|
_engine->destroy(indexBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomGeometry::computeBoundingBox()
|
||||||
|
{
|
||||||
|
float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX;
|
||||||
|
float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < numVertices; i += 3)
|
||||||
|
{
|
||||||
|
minX = std::min(vertices[i], minX);
|
||||||
|
minY = std::min(vertices[i + 1], minY);
|
||||||
|
minZ = std::min(vertices[i + 2], minZ);
|
||||||
|
maxX = std::max(vertices[i], maxX);
|
||||||
|
maxY = std::max(vertices[i + 1], maxY);
|
||||||
|
maxZ = std::max(vertices[i + 2], maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
boundingBox = Box{{minX, minY, minZ}, {maxX, maxY, maxZ}};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace thermion
|
} // namespace thermion
|
||||||
@@ -1206,11 +1206,11 @@ namespace thermion
|
|||||||
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
|
||||||
{
|
{
|
||||||
const auto *geometry = _sceneManager->getGeometry(entityId);
|
const auto *geometry = _sceneManager->getGeometry(entityId);
|
||||||
if (!geometry->uvs)
|
// if (!geometry->uvs)
|
||||||
{
|
// {
|
||||||
Log("No UVS");
|
// Log("No UVS");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
|
// UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
|
||||||
|
|
||||||
|
|||||||
@@ -7,31 +7,26 @@
|
|||||||
#include <filament/TransformManager.h>
|
#include <filament/TransformManager.h>
|
||||||
#include <gltfio/math.h>
|
#include <gltfio/math.h>
|
||||||
#include "SceneManager.hpp"
|
#include "SceneManager.hpp"
|
||||||
#include "material/gizmo.h"
|
#include "material/unlit_fixed_size.h"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
|
||||||
namespace thermion {
|
namespace thermion {
|
||||||
|
|
||||||
using namespace filament::gltfio;
|
using namespace filament::gltfio;
|
||||||
|
|
||||||
Gizmo::Gizmo(Engine *engine, View *view, Scene* scene) : _engine(engine), _view(view), _scene(scene)
|
Gizmo::Gizmo(Engine *engine, View *view, Scene* scene, Material* material) : _engine(engine), _view(view), _scene(scene), _material(material)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto &entityManager = EntityManager::get();
|
auto &entityManager = EntityManager::get();
|
||||||
|
|
||||||
auto &transformManager = _engine->getTransformManager();
|
auto &transformManager = _engine->getTransformManager();
|
||||||
|
|
||||||
_material =
|
|
||||||
Material::Builder()
|
|
||||||
.package(GIZMO_GIZMO_DATA, GIZMO_GIZMO_SIZE)
|
|
||||||
.build(*_engine);
|
|
||||||
|
|
||||||
// First, create the black cube at the center
|
// First, create the black cube at the center
|
||||||
// The axes widgets will be parented to this entity
|
// The axes widgets will be parented to this entity
|
||||||
_entities[3] = entityManager.create();
|
_entities[3] = entityManager.create();
|
||||||
|
|
||||||
_materialInstances[3] = _material->createInstance();
|
_materialInstances[3] = _material->createInstance();
|
||||||
_materialInstances[3]->setParameter("color", math::float4{0.0f, 0.0f, 0.0f, 1.0f}); // Black color
|
_materialInstances[3]->setParameter("baseColorFactor", math::float4{0.0f, 0.0f, 0.0f, 1.0f}); // Black color
|
||||||
|
|
||||||
// Create center cube vertices
|
// Create center cube vertices
|
||||||
float centerCubeSize = 0.01f;
|
float centerCubeSize = 0.01f;
|
||||||
@@ -160,7 +155,7 @@ Gizmo::Gizmo(Engine *engine, View *view, Scene* scene) : _engine(engine), _view(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_materialInstances[i]->setParameter("color", baseColor);
|
_materialInstances[i]->setParameter("baseColorFactor", baseColor);
|
||||||
|
|
||||||
RenderableManager::Builder(1)
|
RenderableManager::Builder(1)
|
||||||
.boundingBox({{-arrowWidth, -arrowWidth, 0},
|
.boundingBox({{-arrowWidth, -arrowWidth, 0},
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ namespace thermion
|
|||||||
if (_isGeometryEntity)
|
if (_isGeometryEntity)
|
||||||
{
|
{
|
||||||
|
|
||||||
Log("Entity %d is geometry", entityId);
|
|
||||||
|
|
||||||
auto geometryEntity = Entity::import(entityId);
|
auto geometryEntity = Entity::import(entityId);
|
||||||
auto renderable = rm.getInstance(geometryEntity);
|
auto renderable = rm.getInstance(geometryEntity);
|
||||||
|
|
||||||
@@ -74,17 +72,7 @@ namespace thermion
|
|||||||
|
|
||||||
auto geometry = sceneManager->getGeometry(entityId);
|
auto geometry = sceneManager->getGeometry(entityId);
|
||||||
|
|
||||||
_entity = utils::EntityManager::get().create();
|
_entity = geometry->createInstance(materialInstance);
|
||||||
RenderableManager::Builder builder(1);
|
|
||||||
builder.boundingBox(geometry->getBoundingBox())
|
|
||||||
.geometry(0, geometry->primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, geometry->numIndices)
|
|
||||||
.culling(true)
|
|
||||||
.material(0, _highlightMaterialInstance)
|
|
||||||
.priority(0)
|
|
||||||
.receiveShadows(false)
|
|
||||||
.castShadows(false);
|
|
||||||
|
|
||||||
builder.build(*engine, _entity);
|
|
||||||
|
|
||||||
scene->addEntity(_entity);
|
scene->addEntity(_entity);
|
||||||
auto outlineTransformInstance = tm.getInstance(_entity);
|
auto outlineTransformInstance = tm.getInstance(_entity);
|
||||||
|
|||||||
@@ -33,9 +33,12 @@
|
|||||||
#include "CustomGeometry.hpp"
|
#include "CustomGeometry.hpp"
|
||||||
#include "UnprojectTexture.hpp"
|
#include "UnprojectTexture.hpp"
|
||||||
|
|
||||||
|
#include "Gizmo.hpp"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "material/image.h"
|
#include "material/image.h"
|
||||||
|
#include "material/unlit_fixed_size.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace thermion
|
namespace thermion
|
||||||
@@ -52,9 +55,8 @@ namespace thermion
|
|||||||
Engine *engine,
|
Engine *engine,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
const char *uberArchivePath,
|
const char *uberArchivePath,
|
||||||
Camera *mainCamera)
|
Camera *mainCamera)
|
||||||
:
|
: _resourceLoaderWrapper(resourceLoaderWrapper),
|
||||||
_resourceLoaderWrapper(resourceLoaderWrapper),
|
|
||||||
_engine(engine),
|
_engine(engine),
|
||||||
_scene(scene),
|
_scene(scene),
|
||||||
_mainCamera(mainCamera)
|
_mainCamera(mainCamera)
|
||||||
@@ -103,17 +105,22 @@ namespace thermion
|
|||||||
_scene->addEntity(_gridOverlay->sphere());
|
_scene->addEntity(_gridOverlay->sphere());
|
||||||
_scene->addEntity(_gridOverlay->grid());
|
_scene->addEntity(_gridOverlay->grid());
|
||||||
|
|
||||||
|
_gizmoMaterial =
|
||||||
|
Material::Builder()
|
||||||
|
.package(UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_DATA, UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE)
|
||||||
|
.build(*_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneManager::~SceneManager()
|
SceneManager::~SceneManager()
|
||||||
{
|
{
|
||||||
for(auto camera : _cameras) {
|
for (auto camera : _cameras)
|
||||||
|
{
|
||||||
auto entity = camera->getEntity();
|
auto entity = camera->getEntity();
|
||||||
_engine->destroyCameraComponent(entity);
|
_engine->destroyCameraComponent(entity);
|
||||||
_engine->getEntityManager().destroy(entity);
|
_engine->getEntityManager().destroy(entity);
|
||||||
}
|
}
|
||||||
_cameras.clear();
|
_cameras.clear();
|
||||||
|
|
||||||
_gridOverlay->destroy();
|
_gridOverlay->destroy();
|
||||||
destroyAll();
|
destroyAll();
|
||||||
|
|
||||||
@@ -131,8 +138,14 @@ namespace thermion
|
|||||||
AssetLoader::destroy(&_assetLoader);
|
AssetLoader::destroy(&_assetLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneManager::isGizmoEntity(Entity entity) {
|
Gizmo *SceneManager::createGizmo(View *view, Scene *scene)
|
||||||
return false; // TODO
|
{
|
||||||
|
return new Gizmo(_engine, view, scene, _gizmoMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneManager::isGizmoEntity(Entity entity)
|
||||||
|
{
|
||||||
|
return false; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
int SceneManager::getInstanceCount(EntityId entityId)
|
int SceneManager::getInstanceCount(EntityId entityId)
|
||||||
@@ -246,15 +259,16 @@ namespace thermion
|
|||||||
return eid;
|
return eid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::setVisibilityLayer(EntityId entityId, int layer) {
|
void SceneManager::setVisibilityLayer(EntityId entityId, int layer)
|
||||||
auto& rm = _engine->getRenderableManager();
|
{
|
||||||
|
auto &rm = _engine->getRenderableManager();
|
||||||
auto renderable = rm.getInstance(utils::Entity::import(entityId));
|
auto renderable = rm.getInstance(utils::Entity::import(entityId));
|
||||||
if(!renderable.isValid()) {
|
if (!renderable.isValid())
|
||||||
|
{
|
||||||
Log("Warning: no renderable found");
|
Log("Warning: no renderable found");
|
||||||
}
|
}
|
||||||
|
|
||||||
rm.setLayerMask(renderable, 0xFF, 1u << layer);
|
rm.setLayerMask(renderable, 0xFF, 1u << layer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync)
|
EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync)
|
||||||
@@ -281,11 +295,13 @@ namespace thermion
|
|||||||
|
|
||||||
_scene->addEntities(asset->getEntities(), entityCount);
|
_scene->addEntities(asset->getEntities(), entityCount);
|
||||||
|
|
||||||
auto & rm = _engine->getRenderableManager();
|
auto &rm = _engine->getRenderableManager();
|
||||||
|
|
||||||
for(int i=0; i < entityCount; i++) {
|
for (int i = 0; i < entityCount; i++)
|
||||||
|
{
|
||||||
auto instance = rm.getInstance(asset->getEntities()[i]);
|
auto instance = rm.getInstance(asset->getEntities()[i]);
|
||||||
if(!instance.isValid()) {
|
if (!instance.isValid())
|
||||||
|
{
|
||||||
Log("No valid renderable for entity");
|
Log("No valid renderable for entity");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -304,13 +320,16 @@ namespace thermion
|
|||||||
_gltfResourceLoader->asyncUpdateLoad();
|
_gltfResourceLoader->asyncUpdateLoad();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(loadResourcesAsync) {
|
if (loadResourcesAsync)
|
||||||
|
{
|
||||||
if (!_gltfResourceLoader->asyncBeginLoad(asset))
|
if (!_gltfResourceLoader->asyncBeginLoad(asset))
|
||||||
{
|
{
|
||||||
Log("Unknown error loading glb asset");
|
Log("Unknown error loading glb asset");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!_gltfResourceLoader->loadResources(asset))
|
if (!_gltfResourceLoader->loadResources(asset))
|
||||||
{
|
{
|
||||||
Log("Unknown error loading glb asset");
|
Log("Unknown error loading glb asset");
|
||||||
@@ -393,6 +412,15 @@ namespace thermion
|
|||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
|
|
||||||
|
if(isGeometryEntity(entityId)) {
|
||||||
|
auto geometry = getGeometry(entityId);
|
||||||
|
auto materialInstance = createUnlitMaterialInstance();
|
||||||
|
auto instanceEntity = geometry->createInstance(materialInstance);
|
||||||
|
_scene->addEntity(instanceEntity);
|
||||||
|
|
||||||
|
return Entity::smuggle(instanceEntity);
|
||||||
|
}
|
||||||
|
|
||||||
const auto &pos = _assets.find(entityId);
|
const auto &pos = _assets.find(entityId);
|
||||||
if (pos == _assets.end())
|
if (pos == _assets.end())
|
||||||
{
|
{
|
||||||
@@ -539,11 +567,13 @@ namespace thermion
|
|||||||
asset.second->getLightEntityCount());
|
asset.second->getLightEntityCount());
|
||||||
_assetLoader->destroyAsset(asset.second);
|
_assetLoader->destroyAsset(asset.second);
|
||||||
}
|
}
|
||||||
for(auto *texture : _textures) {
|
for (auto *texture : _textures)
|
||||||
|
{
|
||||||
_engine->destroy(texture);
|
_engine->destroy(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto *materialInstance : _materialInstances) {
|
for (auto *materialInstance : _materialInstances)
|
||||||
|
{
|
||||||
_engine->destroy(materialInstance);
|
_engine->destroy(materialInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +691,6 @@ namespace thermion
|
|||||||
|
|
||||||
auto entity = Entity::import(entityId);
|
auto entity = Entity::import(entityId);
|
||||||
|
|
||||||
|
|
||||||
if (_animationComponentManager->hasComponent(entity))
|
if (_animationComponentManager->hasComponent(entity))
|
||||||
{
|
{
|
||||||
_animationComponentManager->removeComponent(entity);
|
_animationComponentManager->removeComponent(entity);
|
||||||
@@ -674,10 +703,21 @@ namespace thermion
|
|||||||
|
|
||||||
_scene->remove(entity);
|
_scene->remove(entity);
|
||||||
|
|
||||||
if(isGeometryEntity(entityId)) {
|
if (isGeometryEntity(entityId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
} else if(isGeometryInstance(entityId)) {
|
||||||
|
// destroy renderable
|
||||||
|
auto & rm = _engine->getRenderableManager();
|
||||||
|
auto & em = _engine->getEntityManager();
|
||||||
|
auto instanceEntity = utils::Entity::import(entityId);
|
||||||
|
auto it = std::find(_geometryInstances.begin(), _geometryInstances.end(), entityId);
|
||||||
|
_geometryInstances.erase(it);
|
||||||
|
rm.destroy(instanceEntity);
|
||||||
|
em.destroy(instanceEntity);
|
||||||
|
_engine->destroy(instanceEntity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto *instance = getInstanceByEntityId(entityId);
|
const auto *instance = getInstanceByEntityId(entityId);
|
||||||
|
|
||||||
if (instance)
|
if (instance)
|
||||||
@@ -1412,7 +1452,7 @@ namespace thermion
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneManager::applyTexture(EntityId entityId, Texture *texture, const char* parameterName, int materialIndex)
|
bool SceneManager::applyTexture(EntityId entityId, Texture *texture, const char *parameterName, int materialIndex)
|
||||||
{
|
{
|
||||||
auto entity = Entity::import(entityId);
|
auto entity = Entity::import(entityId);
|
||||||
|
|
||||||
@@ -1446,10 +1486,12 @@ namespace thermion
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::destroyTexture(Texture* texture) {
|
void SceneManager::destroyTexture(Texture *texture)
|
||||||
if(_textures.find(texture) == _textures.end()) {
|
{
|
||||||
|
if (_textures.find(texture) == _textures.end())
|
||||||
|
{
|
||||||
Log("Warning: couldn't find texture");
|
Log("Warning: couldn't find texture");
|
||||||
}
|
}
|
||||||
_textures.erase(texture);
|
_textures.erase(texture);
|
||||||
_engine->destroy(texture);
|
_engine->destroy(texture);
|
||||||
}
|
}
|
||||||
@@ -1904,7 +1946,7 @@ namespace thermion
|
|||||||
tm.setTransform(transformInstance, newTransform);
|
tm.setTransform(transformInstance, newTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::queueRelativePositionUpdateFromViewportVector(View* view, EntityId entityId, float viewportCoordX, float viewportCoordY)
|
void SceneManager::queueRelativePositionUpdateFromViewportVector(View *view, EntityId entityId, float viewportCoordX, float viewportCoordY)
|
||||||
{
|
{
|
||||||
// Get the camera and viewport
|
// Get the camera and viewport
|
||||||
const auto &camera = view->getCamera();
|
const auto &camera = view->getCamera();
|
||||||
@@ -1941,14 +1983,14 @@ namespace thermion
|
|||||||
auto entityPlaneInWorldSpace = camera.getModelMatrix() * entityPlaneInCameraSpace;
|
auto entityPlaneInWorldSpace = camera.getModelMatrix() * entityPlaneInCameraSpace;
|
||||||
|
|
||||||
// Queue the position update (as a relative movement)
|
// Queue the position update (as a relative movement)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::queueTransformUpdates(EntityId* entities, math::mat4* transforms, int numEntities)
|
void SceneManager::queueTransformUpdates(EntityId *entities, math::mat4 *transforms, int numEntities)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
|
|
||||||
for(int i= 0; i < numEntities; i++) {
|
for (int i = 0; i < numEntities; i++)
|
||||||
|
{
|
||||||
auto entity = entities[i];
|
auto entity = entities[i];
|
||||||
const auto &pos = _transformUpdates.find(entity);
|
const auto &pos = _transformUpdates.find(entity);
|
||||||
if (pos == _transformUpdates.end())
|
if (pos == _transformUpdates.end())
|
||||||
@@ -2180,7 +2222,17 @@ namespace thermion
|
|||||||
rm.setPriority(renderableInstance, priority);
|
rm.setPriority(renderableInstance, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
Aabb2 SceneManager::getBoundingBox(View *view, EntityId entityId)
|
Aabb3 SceneManager::getRenderableBoundingBox(EntityId entityId) {
|
||||||
|
auto& rm = _engine->getRenderableManager();
|
||||||
|
auto instance = rm.getInstance(Entity::import(entityId));
|
||||||
|
if(!instance.isValid()) {
|
||||||
|
return Aabb3 {};
|
||||||
|
}
|
||||||
|
auto box = rm.getAxisAlignedBoundingBox(instance);
|
||||||
|
return Aabb3 { box.center.x, box.center.y, box.center.z, box.halfExtent.x, box.halfExtent.y, box.halfExtent.z };
|
||||||
|
}
|
||||||
|
|
||||||
|
Aabb2 SceneManager::getScreenSpaceBoundingBox(View *view, EntityId entityId)
|
||||||
{
|
{
|
||||||
const auto &camera = view->getCamera();
|
const auto &camera = view->getCamera();
|
||||||
const auto &viewport = view->getViewport();
|
const auto &viewport = view->getViewport();
|
||||||
@@ -2279,112 +2331,106 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityId SceneManager::createGeometry(
|
EntityId SceneManager::createGeometry(
|
||||||
float *vertices,
|
float *vertices,
|
||||||
uint32_t numVertices,
|
uint32_t numVertices,
|
||||||
float *normals,
|
float *normals,
|
||||||
uint32_t numNormals,
|
uint32_t numNormals,
|
||||||
float *uvs,
|
float *uvs,
|
||||||
uint32_t numUvs,
|
uint32_t numUvs,
|
||||||
uint16_t *indices,
|
uint16_t *indices,
|
||||||
uint32_t numIndices,
|
uint32_t numIndices,
|
||||||
filament::RenderableManager::PrimitiveType primitiveType,
|
filament::RenderableManager::PrimitiveType primitiveType,
|
||||||
filament::MaterialInstance* materialInstance,
|
filament::MaterialInstance *materialInstance,
|
||||||
bool keepData)
|
bool keepData)
|
||||||
{
|
|
||||||
auto geometry = std::make_unique<CustomGeometry>(vertices, numVertices, normals, numNormals, uvs, numUvs, indices, numIndices, primitiveType, _engine);
|
|
||||||
|
|
||||||
auto entity = utils::EntityManager::get().create();
|
|
||||||
RenderableManager::Builder builder(1);
|
|
||||||
|
|
||||||
builder.boundingBox(geometry->getBoundingBox())
|
|
||||||
.geometry(0, primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, numIndices)
|
|
||||||
.culling(true)
|
|
||||||
.receiveShadows(true)
|
|
||||||
.castShadows(true);
|
|
||||||
|
|
||||||
filament::Material *mat = nullptr;
|
|
||||||
|
|
||||||
if (!materialInstance) {
|
|
||||||
Log("Using default ubershader material");
|
|
||||||
filament::gltfio::MaterialKey config;
|
|
||||||
|
|
||||||
memset(&config, 0, sizeof(config)); // Initialize all bits to zero
|
|
||||||
|
|
||||||
config.unlit = false;
|
|
||||||
config.doubleSided = false;
|
|
||||||
config.useSpecularGlossiness = false;
|
|
||||||
config.alphaMode = filament::gltfio::AlphaMode::OPAQUE;
|
|
||||||
config.hasBaseColorTexture = numUvs > 0;
|
|
||||||
config.hasClearCoat = false;
|
|
||||||
config.hasClearCoatNormalTexture = false;
|
|
||||||
config.hasClearCoatRoughnessTexture = false;
|
|
||||||
config.hasEmissiveTexture = false;
|
|
||||||
config.hasIOR = false;
|
|
||||||
config.hasMetallicRoughnessTexture = false;
|
|
||||||
config.hasNormalTexture = false;
|
|
||||||
config.hasOcclusionTexture = false;
|
|
||||||
config.hasSheen = false;
|
|
||||||
config.hasSheenColorTexture = false;
|
|
||||||
config.hasSheenRoughnessTexture = false;
|
|
||||||
config.hasSpecularGlossinessTexture = false;
|
|
||||||
config.hasTextureTransforms = false;
|
|
||||||
config.hasTransmission = false;
|
|
||||||
config.hasTransmissionTexture = false;
|
|
||||||
config.hasVolume = false;
|
|
||||||
config.hasVolumeThicknessTexture = false;
|
|
||||||
config.baseColorUV = 0;
|
|
||||||
config.hasVertexColors = false;
|
|
||||||
config.hasVolume = false;
|
|
||||||
|
|
||||||
materialInstance = createUbershaderMaterialInstance(config);
|
|
||||||
|
|
||||||
if(!materialInstance) {
|
|
||||||
Log("Failed to create material instance");
|
|
||||||
return Entity::smuggle(Entity());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up texture and sampler if UVs are available
|
|
||||||
if (uvs != nullptr && numUvs > 0)
|
|
||||||
{
|
{
|
||||||
// Create a default white texture
|
auto geometry = std::make_unique<CustomGeometry>(vertices, numVertices, normals, numNormals, uvs, numUvs, indices, numIndices, primitiveType, _engine);
|
||||||
static constexpr uint32_t textureSize = 1;
|
|
||||||
static constexpr uint32_t white = 0x00ffffff;
|
filament::Material *mat = nullptr;
|
||||||
Texture* texture = Texture::Builder()
|
|
||||||
.width(textureSize)
|
|
||||||
.height(textureSize)
|
|
||||||
.levels(1)
|
|
||||||
.format(Texture::InternalFormat::RGBA8)
|
|
||||||
.build(*_engine);
|
|
||||||
|
|
||||||
_textures.insert(texture);
|
if (!materialInstance)
|
||||||
|
{
|
||||||
filament::backend::PixelBufferDescriptor pbd(&white, 4, Texture::Format::RGBA, Texture::Type::UBYTE);
|
Log("Using default ubershader material");
|
||||||
texture->setImage(*_engine, 0, std::move(pbd));
|
filament::gltfio::MaterialKey config;
|
||||||
|
|
||||||
// Create a sampler
|
memset(&config, 0, sizeof(config)); // Initialize all bits to zero
|
||||||
TextureSampler sampler(TextureSampler::MinFilter::NEAREST, TextureSampler::MagFilter::NEAREST);
|
|
||||||
sampler.setWrapModeS(TextureSampler::WrapMode::REPEAT);
|
|
||||||
sampler.setWrapModeT(TextureSampler::WrapMode::REPEAT);
|
|
||||||
|
|
||||||
// Set the texture and sampler to the material instance
|
config.unlit = false;
|
||||||
materialInstance->setParameter("baseColorMap", texture, sampler);
|
config.doubleSided = false;
|
||||||
|
config.useSpecularGlossiness = false;
|
||||||
|
config.alphaMode = filament::gltfio::AlphaMode::OPAQUE;
|
||||||
|
config.hasBaseColorTexture = numUvs > 0;
|
||||||
|
config.hasClearCoat = false;
|
||||||
|
config.hasClearCoatNormalTexture = false;
|
||||||
|
config.hasClearCoatRoughnessTexture = false;
|
||||||
|
config.hasEmissiveTexture = false;
|
||||||
|
config.hasIOR = false;
|
||||||
|
config.hasMetallicRoughnessTexture = false;
|
||||||
|
config.hasNormalTexture = false;
|
||||||
|
config.hasOcclusionTexture = false;
|
||||||
|
config.hasSheen = false;
|
||||||
|
config.hasSheenColorTexture = false;
|
||||||
|
config.hasSheenRoughnessTexture = false;
|
||||||
|
config.hasSpecularGlossinessTexture = false;
|
||||||
|
config.hasTextureTransforms = false;
|
||||||
|
config.hasTransmission = false;
|
||||||
|
config.hasTransmissionTexture = false;
|
||||||
|
config.hasVolume = false;
|
||||||
|
config.hasVolumeThicknessTexture = false;
|
||||||
|
config.baseColorUV = 0;
|
||||||
|
config.hasVertexColors = false;
|
||||||
|
config.hasVolume = false;
|
||||||
|
|
||||||
|
materialInstance = createUbershaderMaterialInstance(config);
|
||||||
|
|
||||||
|
if (!materialInstance)
|
||||||
|
{
|
||||||
|
Log("Failed to create material instance");
|
||||||
|
return Entity::smuggle(Entity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up texture and sampler if UVs are available
|
||||||
|
if (uvs != nullptr && numUvs > 0)
|
||||||
|
{
|
||||||
|
if(materialInstance->getMaterial()->hasParameter("baseColorMap")) {
|
||||||
|
// Create a default white texture
|
||||||
|
static constexpr uint32_t textureSize = 1;
|
||||||
|
static constexpr uint32_t white = 0x00ffffff;
|
||||||
|
Texture *texture = Texture::Builder()
|
||||||
|
.width(textureSize)
|
||||||
|
.height(textureSize)
|
||||||
|
.levels(1)
|
||||||
|
.format(Texture::InternalFormat::RGBA8)
|
||||||
|
.build(*_engine);
|
||||||
|
|
||||||
|
_textures.insert(texture);
|
||||||
|
|
||||||
|
filament::backend::PixelBufferDescriptor pbd(&white, 4, Texture::Format::RGBA, Texture::Type::UBYTE);
|
||||||
|
texture->setImage(*_engine, 0, std::move(pbd));
|
||||||
|
|
||||||
|
// Create a sampler
|
||||||
|
TextureSampler sampler(TextureSampler::MinFilter::NEAREST, TextureSampler::MagFilter::NEAREST);
|
||||||
|
sampler.setWrapModeS(TextureSampler::WrapMode::REPEAT);
|
||||||
|
sampler.setWrapModeT(TextureSampler::WrapMode::REPEAT);
|
||||||
|
|
||||||
|
// Set the texture and sampler to the material instance
|
||||||
|
materialInstance->setParameter("baseColorMap", texture, sampler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto instanceEntity = geometry->createInstance(materialInstance);
|
||||||
|
auto instanceEntityId = Entity::smuggle(instanceEntity);
|
||||||
|
_scene->addEntity(instanceEntity);
|
||||||
|
_geometryInstances.push_back(instanceEntityId);
|
||||||
|
|
||||||
|
_geometry.emplace(instanceEntityId, std::move(geometry));
|
||||||
|
|
||||||
|
return instanceEntityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.material(0, materialInstance);
|
MaterialInstance *SceneManager::getMaterialInstanceAt(EntityId entityId, int materialIndex)
|
||||||
builder.build(*_engine, entity);
|
{
|
||||||
|
|
||||||
_scene->addEntity(entity);
|
|
||||||
|
|
||||||
auto entityId = Entity::smuggle(entity);
|
|
||||||
|
|
||||||
_geometry.emplace(entityId, std::move(geometry));
|
|
||||||
|
|
||||||
return entityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialInstance* SceneManager::getMaterialInstanceAt(EntityId entityId, int materialIndex) {
|
|
||||||
auto entity = Entity::import(entityId);
|
auto entity = Entity::import(entityId);
|
||||||
const auto &rm = _engine->getRenderableManager();
|
const auto &rm = _engine->getRenderableManager();
|
||||||
auto renderableInstance = rm.getInstance(entity);
|
auto renderableInstance = rm.getInstance(entity);
|
||||||
@@ -2436,7 +2482,7 @@ EntityId SceneManager::createGeometry(
|
|||||||
materialInstance->setParameter(property, value);
|
materialInstance->setParameter(property, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::setMaterialProperty(EntityId entityId, int materialIndex, const char *property, filament::math::float4& value)
|
void SceneManager::setMaterialProperty(EntityId entityId, int materialIndex, const char *property, filament::math::float4 &value)
|
||||||
{
|
{
|
||||||
auto entity = Entity::import(entityId);
|
auto entity = Entity::import(entityId);
|
||||||
const auto &rm = _engine->getRenderableManager();
|
const auto &rm = _engine->getRenderableManager();
|
||||||
@@ -2453,17 +2499,20 @@ EntityId SceneManager::createGeometry(
|
|||||||
Log("Parameter %s not found", property);
|
Log("Parameter %s not found", property);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
materialInstance->setParameter(property, filament::math::float4 { value.x, value.y, value.z, value.w });
|
materialInstance->setParameter(property, filament::math::float4{value.x, value.y, value.z, value.w});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::destroy(MaterialInstance* instance) {
|
void SceneManager::destroy(MaterialInstance *instance)
|
||||||
|
{
|
||||||
_engine->destroy(instance);
|
_engine->destroy(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialInstance* SceneManager::createUbershaderMaterialInstance(filament::gltfio::MaterialKey config) {
|
MaterialInstance *SceneManager::createUbershaderMaterialInstance(filament::gltfio::MaterialKey config)
|
||||||
filament::gltfio::UvMap uvmap {};
|
{
|
||||||
auto * materialInstance = _ubershaderProvider->createMaterialInstance(&config, &uvmap);
|
filament::gltfio::UvMap uvmap{};
|
||||||
if(!materialInstance) {
|
auto *materialInstance = _ubershaderProvider->createMaterialInstance(&config, &uvmap);
|
||||||
|
if (!materialInstance)
|
||||||
|
{
|
||||||
Log("Invalid material configuration");
|
Log("Invalid material configuration");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -2473,44 +2522,58 @@ EntityId SceneManager::createGeometry(
|
|||||||
return materialInstance;
|
return materialInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialInstance* SceneManager::createUnlitMaterialInstance() {
|
MaterialInstance *SceneManager::createUnlitFixedSizeMaterialInstance()
|
||||||
|
{
|
||||||
|
auto instance = _gizmoMaterial->createInstance();
|
||||||
|
instance->setParameter("scale", 1.0f);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialInstance *SceneManager::createUnlitMaterialInstance()
|
||||||
|
{
|
||||||
UvMap uvmap;
|
UvMap uvmap;
|
||||||
auto instance = _unlitMaterialProvider->createMaterialInstance(nullptr, &uvmap);
|
auto instance = _unlitMaterialProvider->createMaterialInstance(nullptr, &uvmap);
|
||||||
instance->setParameter("uvScale", filament::math::float2 { 1.0f, 1.0f });
|
instance->setParameter("uvScale", filament::math::float2{1.0f, 1.0f});
|
||||||
_materialInstances.push_back(instance);
|
_materialInstances.push_back(instance);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera* SceneManager::createCamera() {
|
Camera *SceneManager::createCamera()
|
||||||
|
{
|
||||||
auto entity = EntityManager::get().create();
|
auto entity = EntityManager::get().create();
|
||||||
auto camera = _engine->createCamera(entity);
|
auto camera = _engine->createCamera(entity);
|
||||||
_cameras.push_back(camera);
|
_cameras.push_back(camera);
|
||||||
return camera;
|
return camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::destroyCamera(Camera* camera) {
|
void SceneManager::destroyCamera(Camera *camera)
|
||||||
|
{
|
||||||
auto entity = camera->getEntity();
|
auto entity = camera->getEntity();
|
||||||
_engine->destroyCameraComponent(entity);
|
_engine->destroyCameraComponent(entity);
|
||||||
_engine->getEntityManager().destroy(entity);
|
_engine->getEntityManager().destroy(entity);
|
||||||
auto it = std::find(_cameras.begin(), _cameras.end(), camera);
|
auto it = std::find(_cameras.begin(), _cameras.end(), camera);
|
||||||
if(it != _cameras.end()) {
|
if (it != _cameras.end())
|
||||||
|
{
|
||||||
_cameras.erase(it);
|
_cameras.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SceneManager::getCameraCount() {
|
size_t SceneManager::getCameraCount()
|
||||||
|
{
|
||||||
return _cameras.size() + 1;
|
return _cameras.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera* SceneManager::getCameraAt(size_t index) {
|
Camera *SceneManager::getCameraAt(size_t index)
|
||||||
if(index == 0) {
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
return _mainCamera;
|
return _mainCamera;
|
||||||
}
|
}
|
||||||
if(index - 1 > _cameras.size() - 1) {
|
if (index - 1 > _cameras.size() - 1)
|
||||||
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return _cameras[index-1];
|
return _cameras[index - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace thermion
|
} // namespace thermion
|
||||||
|
|||||||
@@ -14,15 +14,6 @@ extern "C"
|
|||||||
using namespace filament;
|
using namespace filament;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TGizmo* Gizmo_new(TEngine *tEngine, TView *tView, TScene *tScene)
|
|
||||||
{
|
|
||||||
auto *view = reinterpret_cast<View*>(tView);
|
|
||||||
auto *engine = reinterpret_cast<Engine*>(tEngine);
|
|
||||||
auto *scene = reinterpret_cast<Scene*>(tScene);
|
|
||||||
auto gizmo = new Gizmo(engine, view, scene);
|
|
||||||
return reinterpret_cast<TGizmo*>(gizmo);
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, uint32_t x, uint32_t y, GizmoPickCallback callback)
|
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, uint32_t x, uint32_t y, GizmoPickCallback callback)
|
||||||
{
|
{
|
||||||
auto *gizmo = reinterpret_cast<Gizmo*>(tGizmo);
|
auto *gizmo = reinterpret_cast<Gizmo*>(tGizmo);
|
||||||
|
|||||||
@@ -173,6 +173,14 @@ extern "C"
|
|||||||
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
|
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TGizmo* SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene) {
|
||||||
|
auto sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||||
|
auto *scene = reinterpret_cast<Scene*>(tScene);
|
||||||
|
auto *view = reinterpret_cast<View*>(tView);
|
||||||
|
auto gizmo = sceneManager->createGizmo(view, scene);
|
||||||
|
return reinterpret_cast<TGizmo*>(gizmo);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync)
|
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync)
|
||||||
{
|
{
|
||||||
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer, loadResourcesAsync);
|
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer, loadResourcesAsync);
|
||||||
@@ -868,7 +876,7 @@ extern "C"
|
|||||||
TMaterialInstance *materialInstance,
|
TMaterialInstance *materialInstance,
|
||||||
bool keepData)
|
bool keepData)
|
||||||
{
|
{
|
||||||
return ((SceneManager *)sceneManager)->createGeometry(vertices, (uint32_t)numVertices, normals, (uint32_t)numNormals, uvs, numUvs, indices, numIndices, (filament::RenderableManager::PrimitiveType)primitiveType, reinterpret_cast<MaterialInstance *>(materialInstance), keepData);
|
return ((SceneManager *)sceneManager)->createGeometry(vertices, static_cast<uint32_t>(numVertices), normals, static_cast<uint32_t>(numNormals), uvs, static_cast<uint32_t>(numUvs), indices, static_cast<uint32_t>(numIndices), (filament::RenderableManager::PrimitiveType)primitiveType, reinterpret_cast<MaterialInstance *>(materialInstance), keepData);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(TSceneManager *sceneManager, const EntityId parent, const char *name)
|
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(TSceneManager *sceneManager, const EntityId parent, const char *name)
|
||||||
@@ -902,17 +910,22 @@ extern "C"
|
|||||||
((SceneManager *)sceneManager)->setPriority(entity, priority);
|
((SceneManager *)sceneManager)->setPriority(entity, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb3 SceneManager_getRenderableBoundingBox(TSceneManager *tSceneManager, EntityId entity) {
|
||||||
|
auto sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
|
||||||
|
return sceneManager->getRenderableBoundingBox(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *tView, EntityId entity)
|
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *tView, EntityId entity)
|
||||||
{
|
{
|
||||||
auto view = reinterpret_cast<View*>(tView);
|
auto view = reinterpret_cast<View*>(tView);
|
||||||
return ((SceneManager *)sceneManager)->getBoundingBox(view, entity);
|
return ((SceneManager *)sceneManager)->getScreenSpaceBoundingBox(view, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *tView, EntityId entity, float *minX, float *minY, float *maxX, float *maxY)
|
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *tView, EntityId entity, float *minX, float *minY, float *maxX, float *maxY)
|
||||||
{
|
{
|
||||||
auto view = reinterpret_cast<View*>(tView);
|
auto view = reinterpret_cast<View*>(tView);
|
||||||
auto box = ((SceneManager *)sceneManager)->getBoundingBox(view, entity);
|
auto box = ((SceneManager *)sceneManager)->getScreenSpaceBoundingBox(view, entity);
|
||||||
*minX = box.minX;
|
*minX = box.minX;
|
||||||
*minY = box.minY;
|
*minY = box.minY;
|
||||||
*maxX = box.maxX;
|
*maxX = box.maxX;
|
||||||
@@ -1026,6 +1039,12 @@ extern "C"
|
|||||||
return reinterpret_cast<TMaterialInstance *>(instance);
|
return reinterpret_cast<TMaterialInstance *>(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitFixedSizeMaterialInstance(TSceneManager *sceneManager)
|
||||||
|
{
|
||||||
|
auto *instance = ((SceneManager *)sceneManager)->createUnlitFixedSizeMaterialInstance();
|
||||||
|
return reinterpret_cast<TMaterialInstance *>(instance);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance)
|
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance)
|
||||||
{
|
{
|
||||||
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance *>(instance));
|
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance *>(instance));
|
||||||
@@ -1041,12 +1060,27 @@ extern "C"
|
|||||||
reinterpret_cast<MaterialInstance *>(materialInstance)->setDepthCulling(enabled);
|
reinterpret_cast<MaterialInstance *>(materialInstance)->setDepthCulling(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *materialInstance, const char *propertyName, double x, double y, double w, double z)
|
||||||
|
{
|
||||||
|
filament::math::float4 data{static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(w)};
|
||||||
|
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y)
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y)
|
||||||
{
|
{
|
||||||
filament::math::float2 data{static_cast<float>(x), static_cast<float>(y)};
|
filament::math::float2 data{static_cast<float>(x), static_cast<float>(y)};
|
||||||
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *materialInstance, const char *propertyName, double value)
|
||||||
|
{
|
||||||
|
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, static_cast<float>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *materialInstance, const char *propertyName, int value)
|
||||||
|
{
|
||||||
|
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, value);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId)
|
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -371,6 +371,16 @@ extern "C"
|
|||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance*)) {
|
||||||
|
std::packaged_task<void()> lambda(
|
||||||
|
[=]() mutable
|
||||||
|
{
|
||||||
|
auto instance = SceneManager_createUnlitFixedSizeMaterialInstance(sceneManager);
|
||||||
|
callback(instance);
|
||||||
|
});
|
||||||
|
auto fut = _rl->add_task(lambda);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager,
|
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager,
|
||||||
const uint8_t *const data,
|
const uint8_t *const data,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
|||||||
@@ -57,154 +57,154 @@ namespace thermion
|
|||||||
uint32_t outputWidth, uint32_t outputHeight)
|
uint32_t outputWidth, uint32_t outputHeight)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto &rm = _engine->getRenderableManager();
|
// auto &rm = _engine->getRenderableManager();
|
||||||
|
|
||||||
auto &tm = _engine->getTransformManager();
|
// auto &tm = _engine->getTransformManager();
|
||||||
|
|
||||||
math::mat4 invViewProj = Camera::inverseProjection(_camera.getProjectionMatrix()) * _camera.getModelMatrix();
|
// math::mat4 invViewProj = Camera::inverseProjection(_camera.getProjectionMatrix()) * _camera.getModelMatrix();
|
||||||
|
|
||||||
auto ti = tm.getInstance(entity);
|
// auto ti = tm.getInstance(entity);
|
||||||
math::mat4f worldTransform = tm.getWorldTransform(ti);
|
// math::mat4f worldTransform = tm.getWorldTransform(ti);
|
||||||
auto inverseWorldTransform = inverse(worldTransform);
|
// auto inverseWorldTransform = inverse(worldTransform);
|
||||||
|
|
||||||
const float *vertices = _geometry->vertices;
|
// const float *vertices = _geometry->vertices;
|
||||||
const float *uvs = _geometry->uvs;
|
// const float *uvs = _geometry->uvs;
|
||||||
const uint16_t *indices = _geometry->indices;
|
// const uint16_t *indices = _geometry->indices;
|
||||||
uint32_t numIndices = _geometry->numIndices;
|
// uint32_t numIndices = _geometry->numIndices;
|
||||||
|
|
||||||
// Create a depth buffer
|
// // Create a depth buffer
|
||||||
std::vector<float> depthBuffer(inputWidth * inputHeight, std::numeric_limits<float>::infinity());
|
// std::vector<float> depthBuffer(inputWidth * inputHeight, std::numeric_limits<float>::infinity());
|
||||||
|
|
||||||
// Create a buffer to store the triangle index for each pixel
|
// // Create a buffer to store the triangle index for each pixel
|
||||||
std::vector<int> triangleIndexBuffer(inputWidth * inputHeight, -1);
|
// std::vector<int> triangleIndexBuffer(inputWidth * inputHeight, -1);
|
||||||
|
|
||||||
auto max = 0.0f;
|
// auto max = 0.0f;
|
||||||
auto min = 99.0f;
|
// auto min = 99.0f;
|
||||||
|
|
||||||
// Depth pre-pass
|
// // Depth pre-pass
|
||||||
for (size_t i = 0; i < numIndices; i += 3)
|
// for (size_t i = 0; i < numIndices; i += 3)
|
||||||
{
|
// {
|
||||||
math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
// math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
||||||
math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
// math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
||||||
math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
// math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
||||||
|
|
||||||
math::float2 uv0(uvs[(indices[i] * 2)], uvs[(indices[i] * 2) + 1]);
|
// math::float2 uv0(uvs[(indices[i] * 2)], uvs[(indices[i] * 2) + 1]);
|
||||||
math::float2 uv1(uvs[(indices[i + 1] * 2)], uvs[(indices[i + 1] * 2) + 1]);
|
// math::float2 uv1(uvs[(indices[i + 1] * 2)], uvs[(indices[i + 1] * 2) + 1]);
|
||||||
math::float2 uv2(uvs[(indices[i + 2] * 2)], uvs[(indices[i + 2] * 2) + 1]);
|
// math::float2 uv2(uvs[(indices[i + 2] * 2)], uvs[(indices[i + 2] * 2) + 1]);
|
||||||
|
|
||||||
// Transform vertices to world space
|
// // Transform vertices to world space
|
||||||
v0 = (worldTransform * math::float4(v0, 1.0f)).xyz;
|
// v0 = (worldTransform * math::float4(v0, 1.0f)).xyz;
|
||||||
v1 = (worldTransform * math::float4(v1, 1.0f)).xyz;
|
// v1 = (worldTransform * math::float4(v1, 1.0f)).xyz;
|
||||||
v2 = (worldTransform * math::float4(v2, 1.0f)).xyz;
|
// v2 = (worldTransform * math::float4(v2, 1.0f)).xyz;
|
||||||
|
|
||||||
// Project vertices to screen space
|
// // Project vertices to screen space
|
||||||
math::float4 clipPos0 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v0, 1.0f);
|
// math::float4 clipPos0 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v0, 1.0f);
|
||||||
math::float4 clipPos1 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v1, 1.0f);
|
// math::float4 clipPos1 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v1, 1.0f);
|
||||||
math::float4 clipPos2 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v2, 1.0f);
|
// math::float4 clipPos2 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v2, 1.0f);
|
||||||
|
|
||||||
math::float3 ndcPos0 = clipPos0.xyz / clipPos0.w;
|
// math::float3 ndcPos0 = clipPos0.xyz / clipPos0.w;
|
||||||
math::float3 ndcPos1 = clipPos1.xyz / clipPos1.w;
|
// math::float3 ndcPos1 = clipPos1.xyz / clipPos1.w;
|
||||||
math::float3 ndcPos2 = clipPos2.xyz / clipPos2.w;
|
// math::float3 ndcPos2 = clipPos2.xyz / clipPos2.w;
|
||||||
|
|
||||||
// Convert NDC to screen coordinates
|
// // Convert NDC to screen coordinates
|
||||||
math::float2 screenPos0((ndcPos0.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos0.y * 0.5f + 0.5f)) * inputHeight);
|
// math::float2 screenPos0((ndcPos0.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos0.y * 0.5f + 0.5f)) * inputHeight);
|
||||||
math::float2 screenPos1((ndcPos1.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos1.y * 0.5f + 0.5f)) * inputHeight);
|
// math::float2 screenPos1((ndcPos1.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos1.y * 0.5f + 0.5f)) * inputHeight);
|
||||||
math::float2 screenPos2((ndcPos2.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos2.y * 0.5f + 0.5f)) * inputHeight);
|
// math::float2 screenPos2((ndcPos2.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos2.y * 0.5f + 0.5f)) * inputHeight);
|
||||||
|
|
||||||
// Compute bounding box of the triangle
|
// // Compute bounding box of the triangle
|
||||||
int minX = std::max(0, static_cast<int>(std::min({screenPos0.x, screenPos1.x, screenPos2.x})));
|
// int minX = std::max(0, static_cast<int>(std::min({screenPos0.x, screenPos1.x, screenPos2.x})));
|
||||||
int maxX = std::min(static_cast<int>(inputWidth) - 1, static_cast<int>(std::max({screenPos0.x, screenPos1.x, screenPos2.x})));
|
// int maxX = std::min(static_cast<int>(inputWidth) - 1, static_cast<int>(std::max({screenPos0.x, screenPos1.x, screenPos2.x})));
|
||||||
int minY = std::max(0, static_cast<int>(std::min({screenPos0.y, screenPos1.y, screenPos2.y})));
|
// int minY = std::max(0, static_cast<int>(std::min({screenPos0.y, screenPos1.y, screenPos2.y})));
|
||||||
int maxY = std::min(static_cast<int>(inputHeight) - 1, static_cast<int>(std::max({screenPos0.y, screenPos1.y, screenPos2.y})));
|
// int maxY = std::min(static_cast<int>(inputHeight) - 1, static_cast<int>(std::max({screenPos0.y, screenPos1.y, screenPos2.y})));
|
||||||
|
|
||||||
// Iterate over the bounding box
|
// // Iterate over the bounding box
|
||||||
for (int y = minY; y <= maxY; ++y)
|
// for (int y = minY; y <= maxY; ++y)
|
||||||
{
|
// {
|
||||||
for (int x = minX; x <= maxX; ++x)
|
// for (int x = minX; x <= maxX; ++x)
|
||||||
{
|
// {
|
||||||
math::float2 pixelPos(x + 0.5f, y + 0.5f);
|
// math::float2 pixelPos(x + 0.5f, y + 0.5f);
|
||||||
|
|
||||||
if (isInsideTriangle(pixelPos, screenPos0, screenPos1, screenPos2))
|
// if (isInsideTriangle(pixelPos, screenPos0, screenPos1, screenPos2))
|
||||||
{
|
// {
|
||||||
math::float3 bary = barycentric(pixelPos, screenPos0, screenPos1, screenPos2);
|
// math::float3 bary = barycentric(pixelPos, screenPos0, screenPos1, screenPos2);
|
||||||
|
|
||||||
// Interpolate depth
|
// // Interpolate depth
|
||||||
float depth = bary.x * ndcPos0.z + bary.y * ndcPos1.z + bary.z * ndcPos2.z;
|
// float depth = bary.x * ndcPos0.z + bary.y * ndcPos1.z + bary.z * ndcPos2.z;
|
||||||
|
|
||||||
// Depth test
|
// // Depth test
|
||||||
if (depth < depthBuffer[y * inputWidth + x])
|
// if (depth < depthBuffer[y * inputWidth + x])
|
||||||
{
|
// {
|
||||||
|
|
||||||
if (depth > max)
|
// if (depth > max)
|
||||||
{
|
// {
|
||||||
max = depth;
|
// max = depth;
|
||||||
}
|
// }
|
||||||
if (depth < min)
|
// if (depth < min)
|
||||||
{
|
// {
|
||||||
min = depth;
|
// min = depth;
|
||||||
}
|
// }
|
||||||
depthBuffer[y * inputWidth + x] = depth;
|
// depthBuffer[y * inputWidth + x] = depth;
|
||||||
triangleIndexBuffer[y * inputWidth + x] = i / 3; // Store triangle index
|
// triangleIndexBuffer[y * inputWidth + x] = i / 3; // Store triangle index
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
for (uint32_t y = 0; y < outputHeight; ++y)
|
// for (uint32_t y = 0; y < outputHeight; ++y)
|
||||||
{
|
// {
|
||||||
for (uint32_t x = 0; x < outputWidth; ++x)
|
// for (uint32_t x = 0; x < outputWidth; ++x)
|
||||||
{
|
// {
|
||||||
|
|
||||||
math::float2 uv(static_cast<float>(x) / outputWidth, static_cast<float>(y) / outputHeight);
|
// math::float2 uv(static_cast<float>(x) / outputWidth, static_cast<float>(y) / outputHeight);
|
||||||
|
|
||||||
// Use the UV coordinates to get the corresponding 3D position on the renderable
|
// // Use the UV coordinates to get the corresponding 3D position on the renderable
|
||||||
math::float3 objectPos;
|
// math::float3 objectPos;
|
||||||
math::float2 interpolatedUV;
|
// math::float2 interpolatedUV;
|
||||||
bool found = false;
|
// bool found = false;
|
||||||
|
|
||||||
// Iterate over triangles to find which one contains this UV coordinate
|
// // Iterate over triangles to find which one contains this UV coordinate
|
||||||
for (size_t i = 0; i < numIndices; i += 3)
|
// for (size_t i = 0; i < numIndices; i += 3)
|
||||||
{
|
// {
|
||||||
math::float2 uv0 = *(math::float2 *)&uvs[indices[i] * 2];
|
// math::float2 uv0 = *(math::float2 *)&uvs[indices[i] * 2];
|
||||||
math::float2 uv1 = *(math::float2 *)&uvs[indices[i + 1] * 2];
|
// math::float2 uv1 = *(math::float2 *)&uvs[indices[i + 1] * 2];
|
||||||
math::float2 uv2 = *(math::float2 *)&uvs[indices[i + 2] * 2];
|
// math::float2 uv2 = *(math::float2 *)&uvs[indices[i + 2] * 2];
|
||||||
|
|
||||||
if (isInsideTriangle(uv, uv0, uv1, uv2))
|
// if (isInsideTriangle(uv, uv0, uv1, uv2))
|
||||||
{
|
// {
|
||||||
// Compute barycentric coordinates in UV space
|
// // Compute barycentric coordinates in UV space
|
||||||
math::float3 bary = barycentric(uv, uv0, uv1, uv2);
|
// math::float3 bary = barycentric(uv, uv0, uv1, uv2);
|
||||||
|
|
||||||
// Interpolate 3D position
|
// // Interpolate 3D position
|
||||||
math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
// math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]);
|
||||||
math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
// math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]);
|
||||||
math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
// math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]);
|
||||||
|
|
||||||
objectPos = v0 * bary.x + v1 * bary.y + v2 * bary.z;
|
// objectPos = v0 * bary.x + v1 * bary.y + v2 * bary.z;
|
||||||
interpolatedUV = uv;
|
// interpolatedUV = uv;
|
||||||
|
|
||||||
// Find the screen coordinates on the input texture
|
// // Find the screen coordinates on the input texture
|
||||||
math::float3 worldPos = (worldTransform * math::float4(objectPos, 1.0f)).xyz;
|
// math::float3 worldPos = (worldTransform * math::float4(objectPos, 1.0f)).xyz;
|
||||||
// Project the world position to screen space
|
// // Project the world position to screen space
|
||||||
math::float4 clipPos = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(worldPos, 1.0f);
|
// math::float4 clipPos = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(worldPos, 1.0f);
|
||||||
math::float3 ndcPos = clipPos.xyz / clipPos.w;
|
// math::float3 ndcPos = clipPos.xyz / clipPos.w;
|
||||||
// Convert NDC to screen coordinates
|
// // Convert NDC to screen coordinates
|
||||||
uint32_t screenX = (ndcPos.x * 0.5f + 0.5f) * inputWidth;
|
// uint32_t screenX = (ndcPos.x * 0.5f + 0.5f) * inputWidth;
|
||||||
uint32_t screenY = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * inputHeight;
|
// uint32_t screenY = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * inputHeight;
|
||||||
|
|
||||||
if (triangleIndexBuffer[(screenY * inputWidth) + screenX] == i / 3)
|
// if (triangleIndexBuffer[(screenY * inputWidth) + screenX] == i / 3)
|
||||||
{
|
// {
|
||||||
if (screenX >= 0 && screenX < inputWidth && screenY >= 0 && screenY < inputHeight)
|
// if (screenX >= 0 && screenX < inputWidth && screenY >= 0 && screenY < inputHeight)
|
||||||
{
|
// {
|
||||||
int inputIndex = (screenY * inputWidth + screenX) * 4;
|
// int inputIndex = (screenY * inputWidth + screenX) * 4;
|
||||||
int outputIndex = (y * outputWidth + x) * 4;
|
// int outputIndex = (y * outputWidth + x) * 4;
|
||||||
std::copy_n(&inputTexture[inputIndex], 4, &outputTexture[outputIndex]);
|
// std::copy_n(&inputTexture[inputIndex], 4, &outputTexture[outputIndex]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace thermion
|
} // namespace thermion
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ add_executable(${MODULE_NAME}
|
|||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Manipulator.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Manipulator.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Bookmark.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Bookmark.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/image.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/image.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/gizmo.c"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/unlit_fixed_size.c"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/ThermionDartWebApi.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/ThermionDartWebApi.cpp"
|
||||||
)
|
)
|
||||||
set_target_properties(${MODULE_NAME} PROPERTIES
|
set_target_properties(${MODULE_NAME} PROPERTIES
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: thermion_dart
|
name: thermion_dart
|
||||||
description: 3D rendering toolkit for Dart.
|
description: 3D rendering toolkit for Dart.
|
||||||
version: 0.2.1-dev.0.0.13
|
version: 0.2.1-dev.0.0.16
|
||||||
homepage: https://thermion.dev
|
homepage: https://thermion.dev
|
||||||
repository: https://github.com/nmfisher/thermion
|
repository: https://github.com/nmfisher/thermion
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ void main() async {
|
|||||||
await viewer
|
await viewer
|
||||||
.setCameraRotation(Quaternion.axisAngle(Vector3(1, 0, 0), -pi / 8));
|
.setCameraRotation(Quaternion.axisAngle(Vector3(1, 0, 0), -pi / 8));
|
||||||
await viewer.setBackgroundColor(1.0, 1.0, 1.0, 1.0);
|
await viewer.setBackgroundColor(1.0, 1.0, 1.0, 1.0);
|
||||||
await viewer
|
final cube = await viewer
|
||||||
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
.createGeometry(GeometryHelper.cube(normals: false, uvs: false));
|
||||||
|
|
||||||
await testHelper.capture(viewer, "geometry_cube_no_uv_no_normal");
|
await testHelper.capture(viewer, "geometry_cube_no_uv_no_normal");
|
||||||
|
await viewer.removeEntity(cube);
|
||||||
|
await testHelper.capture(viewer, "geometry_cube_removed");
|
||||||
|
await viewer.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('create cube (no normals)', () async {
|
test('create cube (no normals)', () async {
|
||||||
@@ -179,5 +182,16 @@ void main() async {
|
|||||||
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
|
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
|
||||||
await testHelper.capture(viewer, "geometry_sphere_no_normals");
|
await testHelper.capture(viewer, "geometry_sphere_no_normals");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('create geometry instance', () async {
|
||||||
|
var viewer = await testHelper.createViewer(
|
||||||
|
cameraPosition: Vector3(0, 0, 6), bg: kRed);
|
||||||
|
final cube = await viewer
|
||||||
|
.createGeometry(GeometryHelper.sphere(normals: false, uvs: false));
|
||||||
|
await viewer.setTransform(cube, Matrix4.translation(Vector3(2, 1, 1)));
|
||||||
|
final cube2 = await viewer.createInstance(cube);
|
||||||
|
await viewer.setTransform(cube2, Matrix4.translation(Vector3(-2, 1, 1)));
|
||||||
|
await testHelper.capture(viewer, "geometry_instance");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,35 @@ void main() async {
|
|||||||
var cube = await viewer.createGeometry(GeometryHelper.cube(),
|
var cube = await viewer.createGeometry(GeometryHelper.cube(),
|
||||||
materialInstance: materialInstance);
|
materialInstance: materialInstance);
|
||||||
|
|
||||||
|
await materialInstance.setParameterFloat4(
|
||||||
|
"baseColorFactor", 0.0, 1.0, 0.0, 1.0);
|
||||||
|
await materialInstance.setParameterInt(
|
||||||
|
"baseColorIndex", -1);
|
||||||
|
|
||||||
|
await testHelper.capture(viewer, "unlit_material_base_color");
|
||||||
|
|
||||||
|
await viewer.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unlit fixed size material', () async {
|
||||||
|
var viewer = await testHelper.createViewer();
|
||||||
|
await viewer.setCameraPosition(0, 0, 6);
|
||||||
|
await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0);
|
||||||
|
await viewer.setPostProcessing(true);
|
||||||
|
await viewer.setToneMapping(ToneMapper.LINEAR);
|
||||||
|
|
||||||
|
var materialInstance = await viewer.createUnlitFixedSizeMaterialInstance();
|
||||||
|
var cube = await viewer.createGeometry(GeometryHelper.cube(),
|
||||||
|
materialInstance: materialInstance);
|
||||||
|
|
||||||
await viewer.setMaterialPropertyFloat4(
|
await viewer.setMaterialPropertyFloat4(
|
||||||
cube, "baseColorFactor", 0, 0.0, 1.0, 0.0, 1.0);
|
cube, "baseColorFactor", 0, 0.0, 1.0, 0.0, 1.0);
|
||||||
|
|
||||||
await testHelper.capture(viewer, "unlit_material_base_color");
|
await testHelper.capture(viewer, "unlit_fixed_size_default_scale");
|
||||||
|
|
||||||
|
await materialInstance.setParameterFloat("scale", 10.0);
|
||||||
|
|
||||||
|
await testHelper.capture(viewer, "unlit_fixed_size_scale_10");
|
||||||
|
|
||||||
await viewer.dispose();
|
await viewer.dispose();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 0.2.1-dev.16
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.1-dev.15
|
||||||
|
|
||||||
|
- **FIX**: multiply coordinates by pixelRatio for scale events.
|
||||||
|
|
||||||
|
## 0.2.1-dev.14
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.2.1-dev.13
|
## 0.2.1-dev.13
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://thermion.dev/quickstart">Quickstart (Flutter)</a> •
|
<a href="https://thermion.dev/quickstart">Quickstart (Flutter)</a> •
|
||||||
<a href="https://thermion.dev/quickstart">Documentation</a> •
|
<a href="https://thermion.dev/quickstart">Documentation</a> •
|
||||||
<a href="https://thermion.dev/examples">Showcase</a> •
|
<a href="https://thermion.dev/showcase">Showcase</a> •
|
||||||
<a href="https://dartpad.thermion.dev/">Playground</a> •
|
<a href="https://dartpad.thermion.dev/">Playground</a> •
|
||||||
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
|
<a href="https://discord.gg/h2VdDK3EAQ">Discord</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -165,12 +165,12 @@ class _MobileListenerWidgetState extends State<_MobileListenerWidget> {
|
|||||||
},
|
},
|
||||||
onScaleStart: (details) async {
|
onScaleStart: (details) async {
|
||||||
await widget.inputHandler.onScaleStart(
|
await widget.inputHandler.onScaleStart(
|
||||||
details.localFocalPoint.toVector2(), details.pointerCount, details.sourceTimeStamp);
|
details.localFocalPoint.toVector2() * widget.pixelRatio, details.pointerCount, details.sourceTimeStamp);
|
||||||
},
|
},
|
||||||
onScaleUpdate: (ScaleUpdateDetails details) async {
|
onScaleUpdate: (ScaleUpdateDetails details) async {
|
||||||
await widget.inputHandler.onScaleUpdate(
|
await widget.inputHandler.onScaleUpdate(
|
||||||
details.localFocalPoint.toVector2(),
|
details.localFocalPoint.toVector2() * widget.pixelRatio,
|
||||||
details.focalPointDelta.toVector2(),
|
details.focalPointDelta.toVector2() * widget.pixelRatio,
|
||||||
details.horizontalScale,
|
details.horizontalScale,
|
||||||
details.verticalScale,
|
details.verticalScale,
|
||||||
details.scale,
|
details.scale,
|
||||||
|
|||||||
@@ -68,12 +68,22 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
var dpr = MediaQuery.of(context).devicePixelRatio;
|
var dpr = MediaQuery.of(context).devicePixelRatio;
|
||||||
|
|
||||||
var size = ((context.findRenderObject()) as RenderBox).size;
|
var size = ((context.findRenderObject()) as RenderBox).size;
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
"Widget size in logical pixels ${size} (pixel ratio : $dpr)");
|
||||||
|
|
||||||
var width = (size.width * dpr).ceil();
|
var width = (size.width * dpr).ceil();
|
||||||
var height = (size.height * dpr).ceil();
|
var height = (size.height * dpr).ceil();
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
"Target texture dimensions ${width}x${height} (pixel ratio : $dpr)");
|
||||||
|
|
||||||
_texture = await ThermionFlutterPlatform.instance
|
_texture = await ThermionFlutterPlatform.instance
|
||||||
.createTexture(widget.view, width, height);
|
.createTexture(widget.view, width, height);
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
"Actual texture dimensions ${_texture!.width}x${_texture!.height} (pixel ratio : $dpr)");
|
||||||
|
|
||||||
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -177,6 +187,9 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
var newWidth = newSize.width.ceil();
|
var newWidth = newSize.width.ceil();
|
||||||
var newHeight = newSize.height.ceil();
|
var newHeight = newSize.height.ceil();
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
"Resizing texture to dimensions ${newWidth}x${newHeight} (pixel ratio : $dpr)");
|
||||||
|
|
||||||
await _texture?.resize(
|
await _texture?.resize(
|
||||||
newWidth,
|
newWidth,
|
||||||
newHeight,
|
newHeight,
|
||||||
@@ -184,6 +197,9 @@ class _ThermionTextureWidgetState extends State<ThermionTextureWidget> {
|
|||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
"Resized texture to dimensions ${_texture!.width}x${_texture!.height} (pixel ratio : $dpr)");
|
||||||
|
|
||||||
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
await widget.view.updateViewport(_texture!.width, _texture!.height);
|
||||||
|
|
||||||
await widget.onResize?.call(
|
await widget.onResize?.call(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: thermion_flutter
|
name: thermion_flutter
|
||||||
description: Flutter plugin for 3D rendering with the Thermion toolkit.
|
description: Flutter plugin for 3D rendering with the Thermion toolkit.
|
||||||
version: 0.2.1-dev.13
|
version: 0.2.1-dev.16
|
||||||
homepage: https://thermion.dev
|
homepage: https://thermion.dev
|
||||||
repository: https://github.com/nmfisher/thermion
|
repository: https://github.com/nmfisher/thermion
|
||||||
|
|
||||||
@@ -17,10 +17,10 @@ dependencies:
|
|||||||
plugin_platform_interface: ^2.0.0
|
plugin_platform_interface: ^2.0.0
|
||||||
ffi: ^2.1.2
|
ffi: ^2.1.2
|
||||||
animation_tools_dart: ^0.1.0
|
animation_tools_dart: ^0.1.0
|
||||||
thermion_dart: ^0.2.1-dev.0.0.13
|
thermion_dart: ^0.2.1-dev.0.0.16
|
||||||
thermion_flutter_platform_interface: ^0.2.1-dev.13
|
thermion_flutter_platform_interface: ^0.2.1-dev.16
|
||||||
thermion_flutter_ffi: ^0.2.1-dev.13
|
thermion_flutter_ffi: ^0.2.1-dev.16
|
||||||
thermion_flutter_web: ^0.2.0+4
|
thermion_flutter_web: ^0.2.0+7
|
||||||
logging: ^1.2.0
|
logging: ^1.2.0
|
||||||
web: ^1.0.0
|
web: ^1.0.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 0.2.1-dev.16
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.1-dev.15
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.1-dev.14
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.2.1-dev.13
|
## 0.2.1-dev.13
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: thermion_flutter_ffi
|
name: thermion_flutter_ffi
|
||||||
description: An FFI implementation for thermion_flutter (i.e. all platforms except web).
|
description: An FFI implementation for thermion_flutter (i.e. all platforms except web).
|
||||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||||
version: 0.2.1-dev.13
|
version: 0.2.1-dev.16
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.3.0 <4.0.0"
|
sdk: ">=3.3.0 <4.0.0"
|
||||||
@@ -23,8 +23,8 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
plugin_platform_interface: ^2.1.0
|
plugin_platform_interface: ^2.1.0
|
||||||
thermion_flutter_platform_interface: ^0.2.1-dev.13
|
thermion_flutter_platform_interface: ^0.2.1-dev.16
|
||||||
thermion_dart: ^0.2.1-dev.0.0.13
|
thermion_dart: ^0.2.1-dev.0.0.16
|
||||||
logging: ^1.2.0
|
logging: ^1.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 0.2.1-dev.16
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.1-dev.15
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.1-dev.14
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.2.1-dev.13
|
## 0.2.1-dev.13
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: thermion_flutter_platform_interface
|
name: thermion_flutter_platform_interface
|
||||||
description: A common platform interface for the thermion_flutter plugin.
|
description: A common platform interface for the thermion_flutter plugin.
|
||||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||||
version: 0.2.1-dev.13
|
version: 0.2.1-dev.16
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.3.0 <4.0.0"
|
sdk: ">=3.3.0 <4.0.0"
|
||||||
@@ -11,7 +11,7 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
plugin_platform_interface: ^2.1.0
|
plugin_platform_interface: ^2.1.0
|
||||||
thermion_dart: ^0.2.1-dev.0.0.13
|
thermion_dart: ^0.2.1-dev.0.0.16
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 0.2.0+7
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.0+6
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.2.0+5
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.2.0+4
|
## 0.2.0+4
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: thermion_flutter_web
|
name: thermion_flutter_web
|
||||||
description: A web platform interface for the thermion_flutter plugin.
|
description: A web platform interface for the thermion_flutter plugin.
|
||||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||||
version: 0.2.0+4
|
version: 0.2.0+7
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.3.0 <4.0.0"
|
sdk: ">=3.3.0 <4.0.0"
|
||||||
@@ -20,8 +20,8 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
plugin_platform_interface: ^2.1.0
|
plugin_platform_interface: ^2.1.0
|
||||||
web: ^1.0.0
|
web: ^1.0.0
|
||||||
thermion_dart: ^0.2.1-dev.0.0.13
|
thermion_dart: ^0.2.1-dev.0.0.16
|
||||||
thermion_flutter_platform_interface: ^0.2.1-dev.13
|
thermion_flutter_platform_interface: ^0.2.1-dev.16
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user