Compare commits
12 Commits
thermion_f
...
thermion_f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7c0eeb7b4 | ||
|
|
fd31b4dcad | ||
|
|
41bf9ededa | ||
|
|
d745712650 | ||
|
|
1df732be7c | ||
|
|
8b413eca52 | ||
|
|
3597077d39 | ||
|
|
7704a06601 | ||
|
|
7b3ad027bf | ||
|
|
cde3af08aa | ||
|
|
7418fb867d | ||
|
|
ce71e09f65 |
123
CHANGELOG.md
123
CHANGELOG.md
@@ -3,6 +3,129 @@
|
|||||||
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-07-23
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Packages with breaking changes:
|
||||||
|
|
||||||
|
- There are no breaking changes in this release.
|
||||||
|
|
||||||
|
Packages with other changes:
|
||||||
|
|
||||||
|
- [`thermion_dart` - `v0.1.3`](#thermion_dart---v013)
|
||||||
|
- [`thermion_flutter_ffi` - `v0.1.0+12`](#thermion_flutter_ffi---v01012)
|
||||||
|
- [`thermion_flutter_web` - `v0.0.3`](#thermion_flutter_web---v003)
|
||||||
|
- [`thermion_flutter_platform_interface` - `v0.1.0+11`](#thermion_flutter_platform_interface---v01011)
|
||||||
|
- [`thermion_flutter` - `v0.1.1+13`](#thermion_flutter---v01113)
|
||||||
|
|
||||||
|
Packages with dependency updates only:
|
||||||
|
|
||||||
|
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
|
||||||
|
|
||||||
|
- `thermion_flutter_platform_interface` - `v0.1.0+11`
|
||||||
|
- `thermion_flutter` - `v0.1.1+13`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `thermion_dart` - `v0.1.3`
|
||||||
|
|
||||||
|
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: shadow JS<->WASM bridge methods.
|
||||||
|
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: shadow JS<->WASM bridge methods.
|
||||||
|
- **FEAT**: add clearMorphAnimationData function.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
|
#### `thermion_flutter_ffi` - `v0.1.0+12`
|
||||||
|
|
||||||
|
- **FIX**: add logging dependency.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: add logging dependency.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
|
||||||
|
#### `thermion_flutter_web` - `v0.0.3`
|
||||||
|
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
|
|
||||||
|
## 2024-07-11
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Packages with breaking changes:
|
||||||
|
|
||||||
|
- There are no breaking changes in this release.
|
||||||
|
|
||||||
|
Packages with other changes:
|
||||||
|
|
||||||
|
- [`thermion_flutter_ffi` - `v0.1.0+11`](#thermion_flutter_ffi---v01011)
|
||||||
|
- [`thermion_flutter` - `v0.1.1+12`](#thermion_flutter---v01112)
|
||||||
|
|
||||||
|
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.1.1+12`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `thermion_flutter_ffi` - `v0.1.0+11`
|
||||||
|
|
||||||
|
- **FIX**: add logging dependency.
|
||||||
|
|
||||||
|
|
||||||
|
## 2024-07-11
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Packages with breaking changes:
|
||||||
|
|
||||||
|
- There are no breaking changes in this release.
|
||||||
|
|
||||||
|
Packages with other changes:
|
||||||
|
|
||||||
|
- [`thermion_dart` - `v0.1.2`](#thermion_dart---v012)
|
||||||
|
- [`thermion_flutter_ffi` - `v0.1.0+10`](#thermion_flutter_ffi---v01010)
|
||||||
|
- [`thermion_flutter_web` - `v0.0.2`](#thermion_flutter_web---v002)
|
||||||
|
- [`thermion_flutter` - `v0.1.1+11`](#thermion_flutter---v01111)
|
||||||
|
- [`thermion_flutter_platform_interface` - `v0.1.0+10`](#thermion_flutter_platform_interface---v01010)
|
||||||
|
|
||||||
|
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.1.1+11`
|
||||||
|
- `thermion_flutter_platform_interface` - `v0.1.0+10`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### `thermion_dart` - `v0.1.2`
|
||||||
|
|
||||||
|
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: shadow JS<->WASM bridge methods.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
|
#### `thermion_flutter_ffi` - `v0.1.0+10`
|
||||||
|
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
|
||||||
|
#### `thermion_flutter_web` - `v0.0.2`
|
||||||
|
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
|
|
||||||
## 2024-07-04
|
## 2024-07-04
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
],
|
],
|
||||||
["Misc.", [
|
["Misc.", [
|
||||||
["Playground", "https://dartpad.thermion.dev"],
|
["Playground", "https://dartpad.thermion.dev"],
|
||||||
["Examples", "/examples"],
|
["Showcase", "/showcase"],
|
||||||
["Windows", "/windows"],
|
["Windows", "/windows"],
|
||||||
["Android", "/android"],
|
["Android", "/android"],
|
||||||
["Contributing", "/contributing"],
|
["Contributing", "/contributing"],
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ and change the minimum deployment target to 13.0:
|
|||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion title="Click to open Windows instructions">
|
<Accordion title="Click to open Windows instructions">
|
||||||
See the [/windows](/Windows) page for steps needed to build on Windows.
|
See the [/windows](/windows) page for steps needed to build on Windows.
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
## 0.1.3
|
||||||
|
|
||||||
|
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: shadow JS<->WASM bridge methods.
|
||||||
|
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: shadow JS<->WASM bridge methods.
|
||||||
|
- **FEAT**: add clearMorphAnimationData function.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
|
## 0.1.2
|
||||||
|
|
||||||
|
- **FIX**: manually remove leading slash for compiler path on Windows when building for Android.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: shadow JS<->WASM bridge methods.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
## 0.1.1+5
|
## 0.1.1+5
|
||||||
|
|
||||||
- Bump "thermion_dart" to `0.1.1+5`.
|
- Bump "thermion_dart" to `0.1.1+5`.
|
||||||
|
|||||||
1
thermion_dart/example/README.md
Normal file
1
thermion_dart/example/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
For an example with both pure Dart and Flutter, see the [example repository](https://github.com/nmfisher/thermion_examples).
|
||||||
@@ -176,9 +176,17 @@ void main(List<String> args) async {
|
|||||||
Architecture.ia32 => "i686-linux-android",
|
Architecture.ia32 => "i686-linux-android",
|
||||||
_ => throw FormatException('Invalid')
|
_ => throw FormatException('Invalid')
|
||||||
};
|
};
|
||||||
var ndkRoot = File(config.cCompiler.compiler!.path).parent.parent.path;
|
|
||||||
|
var compilerPath = config.cCompiler.compiler!.path;
|
||||||
|
|
||||||
|
if(Platform.isWindows && compilerPath.startsWith("/")) {
|
||||||
|
compilerPath = compilerPath.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ndkRoot = File(compilerPath).parent.parent.uri.toFilePath(windows:true);
|
||||||
|
|
||||||
var stlPath =
|
var stlPath =
|
||||||
File("$ndkRoot/sysroot/usr/lib/${archExtension}/libc++_shared.so");
|
File([ndkRoot, "sysroot", "usr", "lib", archExtension, "libc++_shared.so"].join(Platform.pathSeparator));
|
||||||
output.addAsset(NativeCodeAsset(
|
output.addAsset(NativeCodeAsset(
|
||||||
package: "thermion_dart",
|
package: "thermion_dart",
|
||||||
name: "libc++_shared.so",
|
name: "libc++_shared.so",
|
||||||
|
|||||||
@@ -368,6 +368,12 @@ external bool set_morph_animation(
|
|||||||
double frameLengthInMs,
|
double frameLengthInMs,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
||||||
|
external void clear_morph_animation(
|
||||||
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
int entity,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
||||||
external void reset_to_rest_pose(
|
external void reset_to_rest_pose(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
library thermion_flutter_js;
|
library thermion_flutter_js;
|
||||||
|
|
||||||
import 'dart:js_interop';
|
import 'dart:js_interop';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/compatibility/web/interop/thermion_viewer_js_shim.dart';
|
import 'package:thermion_dart/thermion_dart/compatibility/web/interop/thermion_viewer_js_shim.dart';
|
||||||
|
|
||||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||||
@@ -21,6 +22,7 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
///
|
///
|
||||||
@JSExport()
|
@JSExport()
|
||||||
class ThermionViewerJSDartBridge {
|
class ThermionViewerJSDartBridge {
|
||||||
|
final _logger = Logger("ThermionViewerJSDartBridge");
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
|
|
||||||
ThermionViewerJSDartBridge(this.viewer);
|
ThermionViewerJSDartBridge(this.viewer);
|
||||||
@@ -76,7 +78,7 @@ class ThermionViewerJSDartBridge {
|
|||||||
|
|
||||||
@JSExport()
|
@JSExport()
|
||||||
JSPromise loadIbl(String lightingPath, double intensity) {
|
JSPromise loadIbl(String lightingPath, double intensity) {
|
||||||
print("Loading IBL from $lightingPath with intensity $intensity");
|
_logger.info("Loading IBL from $lightingPath with intensity $intensity");
|
||||||
return viewer.loadIbl(lightingPath, intensity: intensity).toJS;
|
return viewer.loadIbl(lightingPath, intensity: intensity).toJS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,13 +132,13 @@ class ThermionViewerJSDartBridge {
|
|||||||
|
|
||||||
@JSExport()
|
@JSExport()
|
||||||
JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
|
JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
|
||||||
print("Loading GLB from path $path with numInstances $numInstances");
|
_logger.info("Loading GLB from path $path with numInstances $numInstances");
|
||||||
return viewer
|
return viewer
|
||||||
.loadGlb(path, numInstances: numInstances)
|
.loadGlb(path, numInstances: numInstances)
|
||||||
.then((entity) => entity.toJS)
|
.then((entity) => entity.toJS)
|
||||||
.catchError((err) {
|
.catchError((err) {
|
||||||
print("Error: $err");
|
_logger.info("Error: $err");
|
||||||
}).toJS;
|
}).toJS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSExport()
|
@JSExport()
|
||||||
@@ -224,6 +226,11 @@ class ThermionViewerJSDartBridge {
|
|||||||
.then((v) => v.toJS)
|
.then((v) => v.toJS)
|
||||||
.toJS;
|
.toJS;
|
||||||
|
|
||||||
|
@JSExport()
|
||||||
|
void clearMorphAnimationData(ThermionEntity entity) {
|
||||||
|
viewer.clearMorphAnimationData(entity);
|
||||||
|
}
|
||||||
|
|
||||||
@JSExport()
|
@JSExport()
|
||||||
JSPromise setMorphAnimationData(
|
JSPromise setMorphAnimationData(
|
||||||
ThermionEntity entity,
|
ThermionEntity entity,
|
||||||
@@ -253,13 +260,13 @@ class ThermionViewerJSDartBridge {
|
|||||||
targetMeshNames: targetMeshNamesDart,
|
targetMeshNames: targetMeshNamesDart,
|
||||||
)
|
)
|
||||||
.onError((err, st) {
|
.onError((err, st) {
|
||||||
print("ERROR SETTING MORPH ANIMATION DATA : $err\n$st");
|
_logger.severe("ERROR SETTING MORPH ANIMATION DATA : $err\n$st");
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
return result.toJS;
|
return result.toJS;
|
||||||
} catch (err, st) {
|
} catch (err, st) {
|
||||||
print(err);
|
_logger.severe(err);
|
||||||
print(st);
|
_logger.severe(st);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -618,7 +625,7 @@ class ThermionViewerJSDartBridge {
|
|||||||
)
|
)
|
||||||
.then((entities) => entities.map((entity) => entity.toJS).toList().toJS)
|
.then((entities) => entities.map((entity) => entity.toJS).toList().toJS)
|
||||||
.onError((e, st) async {
|
.onError((e, st) async {
|
||||||
print("Error : $e\n$st");
|
_logger.severe("Error : $e\n$st");
|
||||||
return <JSNumber>[].toJS;
|
return <JSNumber>[].toJS;
|
||||||
}).toJS;
|
}).toJS;
|
||||||
}
|
}
|
||||||
@@ -632,7 +639,7 @@ class ThermionViewerJSDartBridge {
|
|||||||
)
|
)
|
||||||
.then((entity) => entity.toJS)
|
.then((entity) => entity.toJS)
|
||||||
.onError((e, st) async {
|
.onError((e, st) async {
|
||||||
print("Error getChildEntity : $e\n$st");
|
_logger.severe("Error getChildEntity : $e\n$st");
|
||||||
return 0.toJS;
|
return 0.toJS;
|
||||||
}).toJS;
|
}).toJS;
|
||||||
}
|
}
|
||||||
@@ -720,4 +727,20 @@ class ThermionViewerJSDartBridge {
|
|||||||
{JSFunction? callback, bool affectsTransform = false}) {
|
{JSFunction? callback, bool affectsTransform = false}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSExport()
|
||||||
|
JSPromise setShadowsEnabled(bool enabled) {
|
||||||
|
return viewer.setShadowsEnabled(enabled).toJS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSExport()
|
||||||
|
JSPromise setShadowType(int shadowType) {
|
||||||
|
return viewer.setShadowType(ShadowType.values[shadowType]).toJS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSExport()
|
||||||
|
JSPromise setSoftShadowOptions(
|
||||||
|
double penumbraScale, double penumbraRatioScale) {
|
||||||
|
return viewer.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toJS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:js_interop_unsafe';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/scene.dart';
|
import 'package:thermion_dart/thermion_dart/scene.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ import 'thermion_viewer_js_shim.dart';
|
|||||||
/// a corresponding Javascript shim implementation (see [ThermionViewerJSShim]).
|
/// a corresponding Javascript shim implementation (see [ThermionViewerJSShim]).
|
||||||
///
|
///
|
||||||
class ThermionViewerJS implements ThermionViewer {
|
class ThermionViewerJS implements ThermionViewer {
|
||||||
|
final _logger = Logger("ThermionViewerJS");
|
||||||
late final ThermionViewerJSShim _shim;
|
late final ThermionViewerJSShim _shim;
|
||||||
|
|
||||||
ThermionViewerJS.fromGlobalProperty(String globalPropertyName) {
|
ThermionViewerJS.fromGlobalProperty(String globalPropertyName) {
|
||||||
@@ -261,6 +263,11 @@ class ThermionViewerJS implements ThermionViewer {
|
|||||||
.toDartDouble;
|
.toDartDouble;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> clearMorphAnimationData(ThermionEntity entity) async {
|
||||||
|
_shim.clearMorphAnimationData(entity);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setMorphAnimationData(
|
Future<void> setMorphAnimationData(
|
||||||
ThermionEntity entity, MorphAnimationData animation,
|
ThermionEntity entity, MorphAnimationData animation,
|
||||||
@@ -282,8 +289,8 @@ class ThermionViewerJS implements ThermionViewer {
|
|||||||
targetMeshNamesJS, animation.frameLengthInMs)
|
targetMeshNamesJS, animation.frameLengthInMs)
|
||||||
.toDart;
|
.toDart;
|
||||||
} catch (err, st) {
|
} catch (err, st) {
|
||||||
print(err);
|
_logger.severe(err);
|
||||||
print(st);
|
_logger.severe(st);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -826,17 +833,17 @@ class ThermionViewerJS implements ThermionViewer {
|
|||||||
void onDispose(Future Function() callback) {
|
void onDispose(Future Function() callback) {
|
||||||
_onDispose.add(callback);
|
_onDispose.add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setShadowType(ShadowType shadowType) {
|
Future setShadowType(ShadowType shadowType) {
|
||||||
return _shim.setShadowType(shadowType).toDart;
|
return _shim.setShadowType(shadowType.index).toDart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setShadowsEnabled(bool enabled) {
|
Future setShadowsEnabled(bool enabled) {
|
||||||
return _shim.setShadowsEnabled(enabled).toDart;
|
return _shim.setShadowsEnabled(enabled).toDart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
|
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
|
||||||
return _shim.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toDart;
|
return _shim.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toDart;
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import 'dart:js_interop';
|
|||||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
/// An extension type on [JSObject] that represents a
|
/// An extension type on [JSObject] that represents a
|
||||||
/// Javascript shim implementation of the [ThermionViewer] interface.
|
/// Javascript shim implementation of the [ThermionViewer] interface.
|
||||||
///
|
///
|
||||||
extension type ThermionViewerJSShim(JSObject _) implements JSObject {
|
extension type ThermionViewerJSShim(JSObject _) implements JSObject {
|
||||||
|
|
||||||
@JS('initialized')
|
@JS('initialized')
|
||||||
external JSPromise<JSBoolean> get initialized;
|
external JSPromise<JSBoolean> get initialized;
|
||||||
|
|
||||||
@@ -136,6 +135,9 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
|
|||||||
external JSPromise<JSNumber> getAnimationDuration(
|
external JSPromise<JSNumber> getAnimationDuration(
|
||||||
ThermionEntity entity, int animationIndex);
|
ThermionEntity entity, int animationIndex);
|
||||||
|
|
||||||
|
@JS('clearMorphAnimationData')
|
||||||
|
external void clearMorphAnimationData(ThermionEntity entity);
|
||||||
|
|
||||||
@JS('setMorphAnimationData')
|
@JS('setMorphAnimationData')
|
||||||
external JSPromise setMorphAnimationData(
|
external JSPromise setMorphAnimationData(
|
||||||
ThermionEntity entity,
|
ThermionEntity entity,
|
||||||
@@ -403,19 +405,16 @@ extension type ThermionViewerJSShim(JSObject _) implements JSObject {
|
|||||||
ThermionEntity entity, JSArray<JSNumber> transform);
|
ThermionEntity entity, JSArray<JSNumber> transform);
|
||||||
|
|
||||||
@JS('setBoneTransform')
|
@JS('setBoneTransform')
|
||||||
external JSPromise setBoneTransform(
|
external JSPromise setBoneTransform(ThermionEntity entity, int boneIndex,
|
||||||
ThermionEntity entity, int boneIndex, JSArray<JSNumber> transform, int skinIndex);
|
JSArray<JSNumber> transform, int skinIndex);
|
||||||
|
|
||||||
@JS('setShadowsEnabled')
|
@JS('setShadowsEnabled')
|
||||||
external JSPromise setShadowsEnabled(
|
external JSPromise setShadowsEnabled(bool enabled);
|
||||||
bool enabled);
|
|
||||||
|
|
||||||
@JS('setShadowType')
|
@JS('setShadowType')
|
||||||
external JSPromise setShadowType(
|
external JSPromise setShadowType(int shadowType);
|
||||||
ShadowType shadowType);
|
|
||||||
|
|
||||||
@JS('setSoftShadowOptions')
|
@JS('setSoftShadowOptions')
|
||||||
external JSPromise setSoftShadowOptions(
|
external JSPromise setSoftShadowOptions(
|
||||||
double penumbraScale, double penumbraRatioScale);
|
double penumbraScale, double penumbraRatioScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'dart:js_interop_unsafe';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data' as td;
|
import 'dart:typed_data' as td;
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/scene.dart';
|
import 'package:thermion_dart/thermion_dart/scene.dart';
|
||||||
import 'package:web/web.dart';
|
import 'package:web/web.dart';
|
||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||||
@@ -35,19 +36,48 @@ extension type _EmscriptenModule(JSObject _) implements JSObject {
|
|||||||
|
|
||||||
typedef ThermionViewerImpl = ThermionViewerWasm;
|
typedef ThermionViewerImpl = ThermionViewerWasm;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// A [ThermionViewer] implementation that forwards calls to
|
/// A [ThermionViewer] implementation that forwards calls to the
|
||||||
/// the (Emscripten-generated) ThermionDart JS module.
|
/// (Emscripten-generated) ThermionDart JS module.
|
||||||
///
|
///
|
||||||
class ThermionViewerWasm implements ThermionViewer {
|
class ThermionViewerWasm implements ThermionViewer {
|
||||||
|
final _logger = Logger("ThermionViewerWasm");
|
||||||
|
|
||||||
late _EmscriptenModule _module;
|
late _EmscriptenModule _module;
|
||||||
|
|
||||||
bool _initialized = false;
|
bool _initialized = false;
|
||||||
bool _rendering = false;
|
bool _rendering = false;
|
||||||
|
|
||||||
ThermionViewerWasm({JSObject? module, String moduleName = "thermion_dart"}) {
|
///
|
||||||
_module = module as _EmscriptenModule? ?? window.getProperty<_EmscriptenModule>(moduleName.toJS);
|
/// Construct an instance of this class by explicitly passing the
|
||||||
|
/// module instance via the [module] property, or by specifying [moduleName],
|
||||||
|
/// being the name of the window property where the module has already been
|
||||||
|
/// loaded.
|
||||||
|
///
|
||||||
|
/// Pass [assetPathPrefix] if you need to prepend a path to all asset paths
|
||||||
|
/// (e.g. on Flutter where the asset directory /foo is actually shipped under
|
||||||
|
/// the directory /assets/foo, you would construct this as:
|
||||||
|
///
|
||||||
|
/// final viewer = ThermionViewerWasm(assetPathPrefix:"/assets/")
|
||||||
|
///
|
||||||
|
ThermionViewerWasm(
|
||||||
|
{JSObject? module,
|
||||||
|
String moduleName = "thermion_dart",
|
||||||
|
String? assetPathPrefix}) {
|
||||||
|
_module = module as _EmscriptenModule? ??
|
||||||
|
window.getProperty<_EmscriptenModule>(moduleName.toJS);
|
||||||
|
if (assetPathPrefix != null) {
|
||||||
|
_setAssetPathPrefix(assetPathPrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setAssetPathPrefix(String assetPathPrefix) {
|
||||||
|
_module.ccall(
|
||||||
|
"thermion_dart_web_set_asset_path_prefix",
|
||||||
|
"void",
|
||||||
|
<JSString>["string".toJS].toJS,
|
||||||
|
<JSAny>[assetPathPrefix.toJS].toJS,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSNumber? _viewer;
|
JSNumber? _viewer;
|
||||||
@@ -758,6 +788,27 @@ class ThermionViewerWasm implements ThermionViewer {
|
|||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future clearMorphAnimationData(
|
||||||
|
ThermionEntity entity) async {
|
||||||
|
var meshEntities = await getChildEntities(entity, false);
|
||||||
|
for(final childEntity in meshEntities) {
|
||||||
|
_module.ccall(
|
||||||
|
"clear_morph_animation",
|
||||||
|
"void",
|
||||||
|
[
|
||||||
|
"void*".toJS,
|
||||||
|
"int".toJS,
|
||||||
|
].toJS,
|
||||||
|
[
|
||||||
|
_sceneManager!,
|
||||||
|
childEntity.toJS,
|
||||||
|
].toJS,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setMorphAnimationData(
|
Future setMorphAnimationData(
|
||||||
ThermionEntity entity, MorphAnimationData animation,
|
ThermionEntity entity, MorphAnimationData animation,
|
||||||
@@ -785,7 +836,7 @@ class ThermionViewerWasm implements ThermionViewer {
|
|||||||
var meshEntity = meshEntities[i];
|
var meshEntity = meshEntities[i];
|
||||||
|
|
||||||
if (targetMeshNames?.contains(meshName) == false) {
|
if (targetMeshNames?.contains(meshName) == false) {
|
||||||
// print("Skipping $meshName, not contained in target");
|
// _logger.info("Skipping $meshName, not contained in target");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,7 +844,7 @@ class ThermionViewerWasm implements ThermionViewer {
|
|||||||
|
|
||||||
var meshMorphTargets = await getMorphTargetNames(entity, meshEntity);
|
var meshMorphTargets = await getMorphTargetNames(entity, meshEntity);
|
||||||
|
|
||||||
print("Got mesh morph targets ${meshMorphTargets}");
|
_logger.info("Got mesh morph targets ${meshMorphTargets}");
|
||||||
|
|
||||||
var intersection = animation.morphTargets
|
var intersection = animation.morphTargets
|
||||||
.toSet()
|
.toSet()
|
||||||
@@ -835,35 +886,42 @@ class ThermionViewerWasm implements ThermionViewer {
|
|||||||
// Copy the morph indices to WASM
|
// Copy the morph indices to WASM
|
||||||
_module.writeArrayToMemory(
|
_module.writeArrayToMemory(
|
||||||
idxList.buffer.asUint8List(idxList.offsetInBytes).toJS, idxPtr);
|
idxList.buffer.asUint8List(idxList.offsetInBytes).toJS, idxPtr);
|
||||||
|
bool result = false;
|
||||||
var result = _module.ccall(
|
try {
|
||||||
"set_morph_animation",
|
var jsResult = _module.ccall(
|
||||||
"bool",
|
"set_morph_animation",
|
||||||
[
|
"bool",
|
||||||
"void*".toJS,
|
[
|
||||||
"int".toJS,
|
"void*".toJS,
|
||||||
"float*".toJS,
|
"int".toJS,
|
||||||
"int*".toJS,
|
"float*".toJS,
|
||||||
"int".toJS,
|
"int*".toJS,
|
||||||
"int".toJS,
|
"int".toJS,
|
||||||
"float".toJS
|
"int".toJS,
|
||||||
].toJS,
|
"float".toJS
|
||||||
[
|
].toJS,
|
||||||
_sceneManager!,
|
[
|
||||||
meshEntity.toJS,
|
_sceneManager!,
|
||||||
dataPtr,
|
meshEntity.toJS,
|
||||||
idxPtr,
|
dataPtr,
|
||||||
indices.length.toJS,
|
idxPtr,
|
||||||
animation.numFrames.toJS,
|
indices.length.toJS,
|
||||||
animation.frameLengthInMs.toJS
|
animation.numFrames.toJS,
|
||||||
].toJS,
|
animation.frameLengthInMs.toJS
|
||||||
null) as JSBoolean;
|
].toJS,
|
||||||
|
null);
|
||||||
|
_logger.info("Got jsResult $jsResult");
|
||||||
|
result = (jsResult as JSNumber).toDartInt == 1;
|
||||||
|
} catch (err, st) {
|
||||||
|
_logger.severe(err);
|
||||||
|
_logger.severe(st);
|
||||||
|
}
|
||||||
|
|
||||||
// Free the memory allocated in WASM
|
// Free the memory allocated in WASM
|
||||||
_module._free(dataPtr);
|
_module._free(dataPtr);
|
||||||
_module._free(idxPtr);
|
_module._free(idxPtr);
|
||||||
|
|
||||||
if (!result.toDart) {
|
if (!result) {
|
||||||
throw Exception("Failed to set morph animation data for ${meshName}");
|
throw Exception("Failed to set morph animation data for ${meshName}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1847,29 +1905,22 @@ class ThermionViewerWasm implements ThermionViewer {
|
|||||||
// TODO: implement zoomUpdate
|
// TODO: implement zoomUpdate
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setShadowType(ShadowType shadowType) async {
|
Future setShadowType(ShadowType shadowType) async {
|
||||||
_module.ccall(
|
_module.ccall("set_shadow_type", "void", ["void*".toJS, "int".toJS].toJS,
|
||||||
"set_shadow_type",
|
[_viewer!, shadowType.index.toJS].toJS, null);
|
||||||
"void",
|
|
||||||
["void*".toJS, "int".toJS].toJS,
|
|
||||||
[_viewer!, shadowType.index.toJS].toJS,
|
|
||||||
null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setShadowsEnabled(bool enabled) async {
|
Future setShadowsEnabled(bool enabled) async {
|
||||||
_module.ccall(
|
_module.ccall("set_shadows_enabled", "void",
|
||||||
"set_shadows_enabled",
|
["void*".toJS, "bool".toJS].toJS, [_viewer!, enabled.toJS].toJS, null);
|
||||||
"void",
|
|
||||||
["void*".toJS, "bool".toJS].toJS,
|
|
||||||
[_viewer!, enabled.toJS].toJS,
|
|
||||||
null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) async {
|
Future setSoftShadowOptions(
|
||||||
|
double penumbraScale, double penumbraRatioScale) async {
|
||||||
_module.ccall(
|
_module.ccall(
|
||||||
"set_soft_shadow_options",
|
"set_soft_shadow_options",
|
||||||
"void",
|
"void",
|
||||||
|
|||||||
@@ -269,6 +269,12 @@ abstract class ThermionViewer {
|
|||||||
ThermionEntity entity, MorphAnimationData animation,
|
ThermionEntity entity, MorphAnimationData animation,
|
||||||
{List<String>? targetMeshNames});
|
{List<String>? targetMeshNames});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Clear all current morph animations for [entity].
|
||||||
|
///
|
||||||
|
Future clearMorphAnimationData(
|
||||||
|
ThermionEntity entity);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Resets all bones in the given entity to their rest pose.
|
/// Resets all bones in the given entity to their rest pose.
|
||||||
/// This should be done before every call to addBoneAnimation.
|
/// This should be done before every call to addBoneAnimation.
|
||||||
|
|||||||
@@ -599,6 +599,18 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
return getAnimationDuration(entity, index);
|
return getAnimationDuration(entity, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future clearMorphAnimationData(ThermionEntity entity) async {
|
||||||
|
var meshEntities = await getChildEntities(entity, true);
|
||||||
|
|
||||||
|
for(final childEntity in meshEntities) {
|
||||||
|
clear_morph_animation(
|
||||||
|
_sceneManager!,
|
||||||
|
childEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -586,6 +586,11 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future clearMorphAnimationData(ThermionEntity entity) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setMorphAnimationData(
|
Future setMorphAnimationData(
|
||||||
ThermionEntity entity, MorphAnimationData animation,
|
ThermionEntity entity, MorphAnimationData animation,
|
||||||
@@ -726,19 +731,19 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
// TODO: implement zoomUpdate
|
// TODO: implement zoomUpdate
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setShadowType(ShadowType shadowType) {
|
Future setShadowType(ShadowType shadowType) {
|
||||||
// TODO: implement setShadowType
|
// TODO: implement setShadowType
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setShadowsEnabled(bool enabled) {
|
Future setShadowsEnabled(bool enabled) {
|
||||||
// TODO: implement setShadowsEnabled
|
// TODO: implement setShadowsEnabled
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
|
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
|
||||||
// TODO: implement setSoftShadowOptions
|
// TODO: implement setSoftShadowOptions
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ namespace thermion_filament
|
|||||||
int numFrames,
|
int numFrames,
|
||||||
float frameLengthInMs);
|
float frameLengthInMs);
|
||||||
|
|
||||||
|
void clearMorphAnimationBuffer(
|
||||||
|
EntityId entityId);
|
||||||
|
|
||||||
bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count);
|
bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count);
|
||||||
|
|
||||||
math::mat4f getLocalTransform(EntityId entityId);
|
math::mat4f getLocalTransform(EntityId entityId);
|
||||||
|
|||||||
@@ -136,6 +136,9 @@ extern "C"
|
|||||||
int numMorphTargets,
|
int numMorphTargets,
|
||||||
int numFrames,
|
int numFrames,
|
||||||
float frameLengthInMs);
|
float frameLengthInMs);
|
||||||
|
EMSCRIPTEN_KEEPALIVE void clear_morph_animation(
|
||||||
|
void *sceneManager,
|
||||||
|
EntityId entity);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(
|
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(
|
||||||
void *sceneManager,
|
void *sceneManager,
|
||||||
|
|||||||
@@ -781,6 +781,27 @@ namespace thermion_filament
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneManager::clearMorphAnimationBuffer(
|
||||||
|
EntityId entityId)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(_mutex);
|
||||||
|
|
||||||
|
auto entity = Entity::import(entityId);
|
||||||
|
|
||||||
|
if (entity.isNull())
|
||||||
|
{
|
||||||
|
Log("ERROR: invalid entity %d.", entityId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto animationComponentInstance = _animationComponentManager->getInstance(entity);
|
||||||
|
auto &animationComponent = _animationComponentManager->elementAt<0>(animationComponentInstance);
|
||||||
|
auto &morphAnimations = animationComponent.morphAnimations;
|
||||||
|
|
||||||
|
morphAnimations.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool SceneManager::setMaterialColor(EntityId entityId, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a)
|
bool SceneManager::setMaterialColor(EntityId entityId, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ extern "C"
|
|||||||
return ((SceneManager *)sceneManager)->setMorphTargetWeights(asset, weights, numWeights);
|
return ((SceneManager *)sceneManager)->setMorphTargetWeights(asset, weights, numWeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_morph_animation(
|
EMSCRIPTEN_KEEPALIVE bool set_morph_animation(
|
||||||
void *sceneManager,
|
void *sceneManager,
|
||||||
EntityId asset,
|
EntityId asset,
|
||||||
const float *const morphData,
|
const float *const morphData,
|
||||||
@@ -418,6 +418,10 @@ extern "C"
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void clear_morph_animation(void* sceneManager, EntityId asset) {
|
||||||
|
((SceneManager *)sceneManager)->clearMorphAnimationBuffer(asset);
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(void *sceneManager, EntityId entityId)
|
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(void *sceneManager, EntityId entityId)
|
||||||
{
|
{
|
||||||
((SceneManager *)sceneManager)->resetBones(entityId);
|
((SceneManager *)sceneManager)->resetBones(entityId);
|
||||||
|
|||||||
@@ -15,37 +15,6 @@
|
|||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
#include <emscripten/fetch.h>
|
#include <emscripten/fetch.h>
|
||||||
|
|
||||||
class PendingCall
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PendingCall()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~PendingCall() {}
|
|
||||||
|
|
||||||
void Wait()
|
|
||||||
{
|
|
||||||
std::future<int32_t> accumulate_future = prom.get_future();
|
|
||||||
std::cout << "Loaded asset from Flutter of length " << accumulate_future.get() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleResponse(void* data, int32_t length)
|
|
||||||
{
|
|
||||||
this->data = data;
|
|
||||||
this->length = length;
|
|
||||||
prom.set_value(length);
|
|
||||||
}
|
|
||||||
void* data = nullptr;
|
|
||||||
int32_t length = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::mutex mutex_;
|
|
||||||
std::condition_variable cv_;
|
|
||||||
bool notified_ = false;
|
|
||||||
std::promise<int32_t> prom;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
using emscripten::val;
|
using emscripten::val;
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@@ -60,8 +29,10 @@ extern "C"
|
|||||||
// return 0;
|
// return 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_load_resource_callback(void* data, int32_t length, void* context) {
|
std::string _assetPathPrefix;
|
||||||
((PendingCall*)context)->HandleResponse(data, length);
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void thermion_dart_web_set_asset_path_prefix(const char* prefix) {
|
||||||
|
_assetPathPrefix = std::string(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context() {
|
EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context() {
|
||||||
@@ -160,7 +131,7 @@ extern "C"
|
|||||||
// memcpy(data, request->data, request->numBytes);
|
// memcpy(data, request->data, request->numBytes);
|
||||||
// emscripten_fetch_close(request);
|
// emscripten_fetch_close(request);
|
||||||
// return ResourceBuffer { data, (int32_t) request->numBytes, _lastResourceId } ;
|
// return ResourceBuffer { data, (int32_t) request->numBytes, _lastResourceId } ;
|
||||||
auto pathString = std::string(path);
|
auto pathString = _assetPathPrefix + std::string(path);
|
||||||
void* data = nullptr;
|
void* data = nullptr;
|
||||||
int32_t numBytes = 0;
|
int32_t numBytes = 0;
|
||||||
|
|
||||||
@@ -199,12 +170,10 @@ extern "C"
|
|||||||
EM_ASM({
|
EM_ASM({
|
||||||
var filename = UTF8ToString($0);
|
var filename = UTF8ToString($0);
|
||||||
var data = new Uint8Array(HEAPU8.subarray($1, $1 + $2));
|
var data = new Uint8Array(HEAPU8.subarray($1, $1 + $2));
|
||||||
console.log('Analyinzg /indexed');
|
|
||||||
|
|
||||||
// Ensure the '/indexed' directory exists
|
// Ensure the '/indexed' directory exists
|
||||||
if (!FS.analyzePath('/indexed').exists) {
|
if (!FS.analyzePath('/indexed').exists) {
|
||||||
FS.mkdir('/indexed');
|
FS.mkdir('/indexed');
|
||||||
console.log('Made dir /indexed');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create all parent directories
|
// Create all parent directories
|
||||||
@@ -214,13 +183,10 @@ extern "C"
|
|||||||
currentPath += '/' + parts[i];
|
currentPath += '/' + parts[i];
|
||||||
if (!FS.analyzePath(currentPath).exists) {
|
if (!FS.analyzePath(currentPath).exists) {
|
||||||
FS.mkdir(currentPath);
|
FS.mkdir(currentPath);
|
||||||
console.log("Made dir " + currentPath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('Writing file to /indexed/' + filename);
|
|
||||||
// Write the file
|
// Write the file
|
||||||
FS.writeFile('/indexed/' + filename, data);
|
FS.writeFile('/indexed/' + filename, data);
|
||||||
console.log('File written, syncing');
|
|
||||||
|
|
||||||
FS.syncfs(false, function (err) {
|
FS.syncfs(false, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: thermion_dart
|
name: thermion_dart
|
||||||
description: 3D rendering toolkit for Dart.
|
description: 3D rendering toolkit for Dart.
|
||||||
version: 0.1.1+5
|
version: 0.1.3
|
||||||
homepage: https://thermion.dev
|
homepage: https://thermion.dev
|
||||||
repository: https://github.com/nmfisher/thermion
|
repository: https://github.com/nmfisher/thermion
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 0.1.1+13
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.1.1+12
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.1.1+11
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.1.1+10
|
## 0.1.1+10
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
96
thermion_flutter/thermion_flutter/example/README.md
Normal file
96
thermion_flutter/thermion_flutter/example/README.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
For a more thorough example with both Flutter and pure Dart, see the [example repository](https://github.com/nmfisher/thermion_examples).
|
||||||
|
|
||||||
|
[flutter/quickstart/lib/main.dart](https://github.com/nmfisher/thermion_examples/blob/master/flutter/quickstart/lib/main.dart)
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:thermion_flutter/thermion_flutter.dart';
|
||||||
|
|
||||||
|
import 'package:vector_math/vector_math_64.dart' as v;
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(const MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'Flutter Demo',
|
||||||
|
theme: ThemeData(
|
||||||
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyHomePage extends StatefulWidget {
|
||||||
|
const MyHomePage({super.key, required this.title});
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MyHomePage> createState() => _MyHomePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
bool _loaded = false;
|
||||||
|
ThermionViewer? _thermionViewer;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _load() async {
|
||||||
|
var viewer = await ThermionFlutterPlugin.createViewer();
|
||||||
|
_thermionViewer = viewer;
|
||||||
|
_thermionViewer!.loadSkybox("assets/default_env_skybox.ktx");
|
||||||
|
_thermionViewer!.loadGlb("assets/cube.glb");
|
||||||
|
|
||||||
|
_thermionViewer!.setCameraPosition(0, 1, 10);
|
||||||
|
_thermionViewer!.setCameraRotation(
|
||||||
|
v.Quaternion.axisAngle(v.Vector3(1, 0, 0), -30 / 180 * pi) *
|
||||||
|
v.Quaternion.axisAngle(v.Vector3(0, 1, 0), 15 / 180 * pi));
|
||||||
|
_thermionViewer!.addLight(LightType.SUN, 7500, 50000, 0, 0, 0, 1, -1, -1);
|
||||||
|
_thermionViewer!.setRendering(true);
|
||||||
|
_loaded = true;
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _unload() async {
|
||||||
|
var viewer = _thermionViewer!;
|
||||||
|
_thermionViewer = null;
|
||||||
|
setState(() {});
|
||||||
|
await viewer.dispose();
|
||||||
|
_loaded = false;
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _loadButton() {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(child: const Text("Load"), onPressed: _load));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _unloadButton() {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(child: const Text("Unload"), onPressed: _unload));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(children: [
|
||||||
|
if (_thermionViewer != null)
|
||||||
|
Positioned.fill(child: ThermionWidget(viewer: _thermionViewer!)),
|
||||||
|
if (!_loaded) _loadButton(),
|
||||||
|
if (_loaded) _unloadButton(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
@@ -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.1.1+10
|
version: 0.1.1+13
|
||||||
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.0.4
|
animation_tools_dart: ^0.0.4
|
||||||
thermion_dart: ^0.1.1+5
|
thermion_dart: ^0.1.3
|
||||||
thermion_flutter_platform_interface: ^0.1.0+9
|
thermion_flutter_platform_interface: ^0.1.0+11
|
||||||
thermion_flutter_ffi: ^0.1.0+9
|
thermion_flutter_ffi: ^0.1.0+12
|
||||||
thermion_flutter_web: ^0.0.1+9
|
thermion_flutter_web: ^0.0.3
|
||||||
logging: ^1.2.0
|
logging: ^1.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
## 0.1.0+12
|
||||||
|
|
||||||
|
- **FIX**: add logging dependency.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
- **FIX**: add logging dependency.
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
|
||||||
|
## 0.1.0+11
|
||||||
|
|
||||||
|
- **FIX**: add logging dependency.
|
||||||
|
|
||||||
|
## 0.1.0+10
|
||||||
|
|
||||||
|
- **FIX**: web/JS bool checks need to compare to int.
|
||||||
|
|
||||||
## 0.1.0+9
|
## 0.1.0+9
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:thermion_dart/thermion_dart.dart';
|
|||||||
import 'package:thermion_dart/thermion_dart/thermion_viewer_ffi.dart';
|
import 'package:thermion_dart/thermion_dart/thermion_viewer_ffi.dart';
|
||||||
import 'package:thermion_flutter_platform_interface/thermion_flutter_platform_interface.dart';
|
import 'package:thermion_flutter_platform_interface/thermion_flutter_platform_interface.dart';
|
||||||
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';
|
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
/// An implementation of [ThermionFlutterPlatform] that uses a Flutter platform
|
/// An implementation of [ThermionFlutterPlatform] that uses a Flutter platform
|
||||||
@@ -13,6 +14,7 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dar
|
|||||||
///
|
///
|
||||||
class ThermionFlutterFFI extends ThermionFlutterPlatform {
|
class ThermionFlutterFFI extends ThermionFlutterPlatform {
|
||||||
final _channel = const MethodChannel("dev.thermion.flutter/event");
|
final _channel = const MethodChannel("dev.thermion.flutter/event");
|
||||||
|
final _logger = Logger("ThermionFlutterFFI");
|
||||||
|
|
||||||
ThermionViewerFFI? _viewer;
|
ThermionViewerFFI? _viewer;
|
||||||
|
|
||||||
@@ -133,7 +135,7 @@ class ThermionFlutterFFI extends ThermionFlutterPlatform {
|
|||||||
final hardwareTextureId = result[1] as int?;
|
final hardwareTextureId = result[1] as int?;
|
||||||
final surfaceAddress = result[2] as int?;
|
final surfaceAddress = result[2] as int?;
|
||||||
|
|
||||||
print(
|
_logger.info(
|
||||||
"Created texture with flutter texture id ${flutterTextureId}, hardwareTextureId $hardwareTextureId and surfaceAddress $surfaceAddress");
|
"Created texture with flutter texture id ${flutterTextureId}, hardwareTextureId $hardwareTextureId and surfaceAddress $surfaceAddress");
|
||||||
|
|
||||||
_viewer?.viewportDimensions = (width.toDouble(), height.toDouble());
|
_viewer?.viewportDimensions = (width.toDouble(), height.toDouble());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: thermion_flutter_ffi
|
name: thermion_flutter_ffi
|
||||||
description: An FFI interface for the thermion_flutter plugin (all platforms except web).
|
description: An FFI interface for the thermion_flutter plugin (all platforms except web).
|
||||||
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
repository: https://github.com/nmfisher/thermion_flutter/thermion_flutter
|
||||||
version: 0.1.0+9
|
version: 0.1.0+12
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.3.0 <4.0.0"
|
sdk: ">=3.3.0 <4.0.0"
|
||||||
@@ -22,8 +22,9 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
plugin_platform_interface: ^2.1.0
|
plugin_platform_interface: ^2.1.0
|
||||||
thermion_flutter_platform_interface: ^0.1.0+9
|
thermion_flutter_platform_interface: ^0.1.0+11
|
||||||
thermion_dart: ^0.1.1+5
|
thermion_dart: ^0.1.3
|
||||||
|
logging: ^1.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
## 0.1.0+11
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
|
## 0.1.0+10
|
||||||
|
|
||||||
|
- Update a dependency to the latest release.
|
||||||
|
|
||||||
## 0.1.0+9
|
## 0.1.0+9
|
||||||
|
|
||||||
- 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.1.0+9
|
version: 0.1.0+11
|
||||||
|
|
||||||
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.1.1+5
|
thermion_dart: ^0.1.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
## 0.0.3
|
||||||
|
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
|
## 0.0.2
|
||||||
|
|
||||||
|
- **FEAT**: allow passing assetPathPrefix to ThermionViewerWasm to account for Flutter build asset paths.
|
||||||
|
|
||||||
## 0.0.1+9
|
## 0.0.1+9
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
- Update a dependency to the latest release.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class ThermionFlutterWebPlugin extends ThermionFlutterPlatform {
|
|||||||
var width = window.innerWidth;
|
var width = window.innerWidth;
|
||||||
var height = window.innerHeight;
|
var height = window.innerHeight;
|
||||||
|
|
||||||
var viewer = ThermionViewerWasm();
|
var viewer = ThermionViewerWasm(assetPathPrefix: "/assets/");
|
||||||
await viewer.initialize(width, height, uberArchivePath: uberArchivePath);
|
await viewer.initialize(width, height, uberArchivePath: uberArchivePath);
|
||||||
return viewer;
|
return viewer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.0.1+9
|
version: 0.0.3
|
||||||
|
|
||||||
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: ^0.5.1
|
web: ^0.5.1
|
||||||
thermion_dart: ^0.1.1+5
|
thermion_dart: ^0.1.3
|
||||||
thermion_flutter_platform_interface: ^0.1.0+9
|
thermion_flutter_platform_interface: ^0.1.0+11
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user