feat! js_interop improvements
This commit is contained in:
21
examples/dart/js_wasm/pubspec.yaml
Normal file
21
examples/dart/js_wasm/pubspec.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
name: example_web
|
||||
description: A sample command-line application.
|
||||
version: 1.0.0
|
||||
# repository: https://github.com/my_org/my_repo
|
||||
|
||||
environment:
|
||||
sdk: ^3.3.0
|
||||
|
||||
dependencies:
|
||||
thermion_dart:
|
||||
path: ../../../thermion_dart
|
||||
native_toolchain_c: ^0.9.0
|
||||
native_assets_cli: ^0.12.0
|
||||
logging: ^1.3.0
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^3.0.0
|
||||
test: ^1.24.0
|
||||
build_runner: ^2.4.13
|
||||
build_test: ^2.2.2
|
||||
build_web_compilers: ^4.0.11
|
||||
1
examples/dart/js_wasm/web/assets
Symbolic link
1
examples/dart/js_wasm/web/assets
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../assets/
|
||||
102
examples/dart/js_wasm/web/example.dart
Normal file
102
examples/dart/js_wasm/web/example.dart
Normal file
@@ -0,0 +1,102 @@
|
||||
import 'dart:async';
|
||||
import 'dart:js_interop';
|
||||
import 'dart:math';
|
||||
import 'package:web/web.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart' hide NativeLibrary;
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/resource_loader.dart';
|
||||
import 'web_input_handler.dart';
|
||||
import 'package:thermion_dart/src/bindings/src/thermion_dart_js_interop.g.dart';
|
||||
|
||||
void main(List<String> arguments) async {
|
||||
Logger.root.onRecord.listen((record) {
|
||||
print(record);
|
||||
});
|
||||
|
||||
NativeLibrary.initBindings("thermion_dart");
|
||||
|
||||
final canvas =
|
||||
document.getElementById("thermion_canvas") as HTMLCanvasElement;
|
||||
try {
|
||||
canvas.width = canvas.clientWidth;
|
||||
canvas.height = canvas.clientHeight;
|
||||
} catch (err) {
|
||||
print(err.toString());
|
||||
}
|
||||
|
||||
final config =
|
||||
FFIFilamentConfig(sharedContext: nullptr.cast(), backend: Backend.OPENGL);
|
||||
|
||||
await FFIFilamentApp.create(config: config);
|
||||
|
||||
var swapChain = await FilamentApp.instance!
|
||||
.createHeadlessSwapChain(canvas.width, canvas.height);
|
||||
final viewer = ThermionViewerFFI(loadAssetFromUri: defaultResourceLoader);
|
||||
await viewer.initialized;
|
||||
await FilamentApp.instance!.setClearOptions(1.0, 0.0, 0.0, 1.0);
|
||||
await FilamentApp.instance!.register(swapChain, viewer.view);
|
||||
await viewer.setViewport(canvas.width, canvas.height);
|
||||
await viewer.setRendering(true);
|
||||
final rnd = Random();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
bool resizing = false;
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
final resizer = () async {
|
||||
if (resizing) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
resizing = true;
|
||||
await viewer.setViewport(canvas.clientWidth, canvas.clientHeight);
|
||||
Thermion_resizeCanvas(canvas.clientWidth, canvas.clientHeight);
|
||||
} catch (err) {
|
||||
print(err);
|
||||
} finally {
|
||||
resizing = false;
|
||||
}
|
||||
};
|
||||
// ignore: unused_local_variable, prefer_function_declarations_over_variables
|
||||
final jsWrapper = () {
|
||||
var promise = resizer().toJS;
|
||||
return promise;
|
||||
};
|
||||
window.addEventListener('resize', jsWrapper.toJS);
|
||||
// // await FilamentApp.instance!.render();
|
||||
// // await Future.delayed(Duration(seconds: 1));
|
||||
|
||||
// // await FilamentApp.instance!.setClearOptions(1.0, 1.0, 0.0, 1.0);
|
||||
// // await FilamentApp.instance!.render();
|
||||
// // await Future.delayed(Duration(seconds: 1));
|
||||
|
||||
await viewer.loadSkybox("assets/default_env_skybox.ktx");
|
||||
await viewer.loadGltf("assets/cube.glb");
|
||||
final camera = await viewer.getActiveCamera();
|
||||
|
||||
var zOffset = 10.0;
|
||||
|
||||
final inputHandler = DelegateInputHandler.flight(viewer);
|
||||
|
||||
final webInputHandler =
|
||||
WebInputHandler(inputHandler: inputHandler, canvas: canvas);
|
||||
await camera.lookAt(Vector3(0, 0, zOffset));
|
||||
DateTime lastRender = DateTime.now();
|
||||
|
||||
while (true) {
|
||||
var stackPtr = stackSave();
|
||||
var now = DateTime.now();
|
||||
await FilamentApp.instance!.requestFrame();
|
||||
now = DateTime.now();
|
||||
var timeSinceLast =
|
||||
now.microsecondsSinceEpoch - lastRender.microsecondsSinceEpoch;
|
||||
lastRender = now;
|
||||
if (timeSinceLast < 1667) {
|
||||
var waitFor = 1667 - timeSinceLast;
|
||||
await Future.delayed(Duration(microseconds: waitFor));
|
||||
}
|
||||
stackRestore(stackPtr);
|
||||
// inputHandler.keyDown(PhysicalKey.S);
|
||||
// await camera.lookAt(Vector3(0,0,zOffset));
|
||||
// zOffset +=0.1;
|
||||
}
|
||||
}
|
||||
35
examples/dart/js_wasm/web/index_js.html
Normal file
35
examples/dart/js_wasm/web/index_js.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="./thermion_dart.js"></script>
|
||||
<script type="module">
|
||||
try {
|
||||
window.thermion_dart = await thermion_dart();
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
const script = document.createElement('script')
|
||||
script.src = 'example.dart.js'
|
||||
document.head.append(script);
|
||||
</script>
|
||||
<style>
|
||||
html, body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
canvas {
|
||||
position:absolute;
|
||||
left:0;
|
||||
right:0;
|
||||
top:0;
|
||||
bottom:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="thermion_canvas"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
35
examples/dart/js_wasm/web/index_wasm.html
Normal file
35
examples/dart/js_wasm/web/index_wasm.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="thermion_dart.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
canvas {
|
||||
position:absolute;
|
||||
left:0;
|
||||
right:0;
|
||||
top:0;
|
||||
bottom:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<script type="module">
|
||||
try {
|
||||
window.thermion_dart = await thermion_dart();
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
const dartModulePromise = WebAssembly.compileStreaming(fetch('example.wasm'));
|
||||
const imports = {};
|
||||
const dart2wasm_runtime = await import('./example.mjs');
|
||||
const moduleInstance = await dart2wasm_runtime.instantiate(dartModulePromise, imports);
|
||||
await dart2wasm_runtime.invoke(moduleInstance);
|
||||
</script>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
22
examples/dart/js_wasm/web/main.js
Normal file
22
examples/dart/js_wasm/web/main.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { readFile } from 'fs/promises';
|
||||
|
||||
import { compile } from './example.mjs';
|
||||
import thermion_dart from './thermion_dart.js';
|
||||
|
||||
|
||||
async function runDartWasm() {
|
||||
globalThis['thermion_dart'] = await thermion_dart();
|
||||
|
||||
const wasmBytes = await readFile('example.wasm');
|
||||
const compiledApp = await compile(wasmBytes);
|
||||
const instantiatedApp = await compiledApp.instantiate({});
|
||||
try {
|
||||
instantiatedApp.invokeMain();
|
||||
} catch(err) {
|
||||
console.error("Failed");
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
runDartWasm().catch(console.error);
|
||||
|
||||
1
examples/dart/js_wasm/web/thermion_dart.js
Symbolic link
1
examples/dart/js_wasm/web/thermion_dart.js
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../thermion_dart/native/web/build/build/out/thermion_dart.js
|
||||
1
examples/dart/js_wasm/web/thermion_dart.wasm
Symbolic link
1
examples/dart/js_wasm/web/thermion_dart.wasm
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../thermion_dart/native/web/build/build/out/thermion_dart.wasm
|
||||
233
examples/dart/js_wasm/web/web_input_handler.dart
Normal file
233
examples/dart/js_wasm/web/web_input_handler.dart
Normal file
@@ -0,0 +1,233 @@
|
||||
import 'dart:js_interop';
|
||||
|
||||
import 'package:web/web.dart' as web;
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class WebInputHandler {
|
||||
final DelegateInputHandler inputHandler;
|
||||
final web.HTMLCanvasElement canvas;
|
||||
late double pixelRatio;
|
||||
|
||||
final Map<int, Vector2> _touchPositions = {};
|
||||
|
||||
WebInputHandler({
|
||||
required this.inputHandler,
|
||||
required this.canvas,
|
||||
}) {
|
||||
pixelRatio = web.window.devicePixelRatio;
|
||||
_initializeEventListeners();
|
||||
}
|
||||
|
||||
void _initializeEventListeners() {
|
||||
canvas.addEventListener('mousedown', _onMouseDown.toJS);
|
||||
canvas.addEventListener('mousemove', _onMouseMove.toJS);
|
||||
canvas.addEventListener('mouseup', _onMouseUp.toJS);
|
||||
canvas.addEventListener('wheel', _onMouseWheel.toJS);
|
||||
web.window.addEventListener('keydown', _onKeyDown.toJS);
|
||||
web.window.addEventListener('keyup', _onKeyUp.toJS);
|
||||
|
||||
canvas.addEventListener('touchstart', _onTouchStart.toJS);
|
||||
canvas.addEventListener('touchmove', _onTouchMove.toJS);
|
||||
canvas.addEventListener('touchend', _onTouchEnd.toJS);
|
||||
canvas.addEventListener('touchcancel', _onTouchCancel.toJS);
|
||||
}
|
||||
|
||||
void _onMouseDown(web.MouseEvent event) {
|
||||
final localPos = _getLocalPositionFromEvent(event);
|
||||
final isMiddle = event.button == 1;
|
||||
inputHandler.onPointerDown(localPos, isMiddle);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onMouseMove(web.MouseEvent event) {
|
||||
final localPos = _getLocalPositionFromEvent(event);
|
||||
|
||||
final delta = Vector2(event.movementX ?? 0, event.movementY ?? 0);
|
||||
final isMiddle = event.buttons & 4 != 0;
|
||||
inputHandler.onPointerMove(localPos, delta, isMiddle);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onMouseUp(web.MouseEvent event) {
|
||||
final isMiddle = event.button == 1;
|
||||
inputHandler.onPointerUp(isMiddle);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onMouseWheel(web.WheelEvent event) {
|
||||
final localPos = _getLocalPositionFromEvent(event);
|
||||
final delta = event.deltaY;
|
||||
inputHandler.onPointerScroll(localPos, delta);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onKeyDown(web.KeyboardEvent event) {
|
||||
PhysicalKey? key;
|
||||
switch (event.code) {
|
||||
case 'KeyW':
|
||||
key = PhysicalKey.W;
|
||||
break;
|
||||
case 'KeyA':
|
||||
key = PhysicalKey.A;
|
||||
break;
|
||||
case 'KeyS':
|
||||
key = PhysicalKey.S;
|
||||
break;
|
||||
case 'KeyD':
|
||||
key = PhysicalKey.D;
|
||||
break;
|
||||
}
|
||||
if (key != null) inputHandler.keyDown(key);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onKeyUp(web.KeyboardEvent event) {
|
||||
PhysicalKey? key;
|
||||
switch (event.code) {
|
||||
case 'KeyW':
|
||||
key = PhysicalKey.W;
|
||||
break;
|
||||
case 'KeyA':
|
||||
key = PhysicalKey.A;
|
||||
break;
|
||||
case 'KeyS':
|
||||
key = PhysicalKey.S;
|
||||
break;
|
||||
case 'KeyD':
|
||||
key = PhysicalKey.D;
|
||||
break;
|
||||
}
|
||||
if (key != null) inputHandler.keyUp(key);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onTouchStart(web.TouchEvent event) {
|
||||
|
||||
for (var touch in event.changedTouches.toList()) {
|
||||
final pos = _getLocalPositionFromTouch(touch);
|
||||
_touchPositions[touch.identifier] = pos;
|
||||
}
|
||||
|
||||
final touchCount = event.touches.toList().length;
|
||||
if (touchCount == 1) {
|
||||
final touch = event.touches.toList().first;
|
||||
final pos = _getLocalPositionFromTouch(touch);
|
||||
inputHandler.onPointerDown(pos, false);
|
||||
}
|
||||
|
||||
_handleScaleStart(touchCount, null);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onTouchMove(web.TouchEvent event) {
|
||||
for (var touch in event.changedTouches.toList()) {
|
||||
final id = touch.identifier;
|
||||
final currPos = _getLocalPositionFromTouch(touch);
|
||||
final prevPos = _touchPositions[id];
|
||||
|
||||
if (prevPos != null) {
|
||||
final delta = currPos - prevPos;
|
||||
inputHandler.onPointerMove(currPos, delta, false);
|
||||
}
|
||||
|
||||
_touchPositions[id] = currPos;
|
||||
}
|
||||
|
||||
final touchCount = event.touches.toList().length;
|
||||
if (touchCount >= 2) {
|
||||
final touches = event.touches.toList().toList();
|
||||
final touch0 = touches[0];
|
||||
final touch1 = touches[1];
|
||||
final pos0 = _getLocalPositionFromTouch(touch0);
|
||||
final pos1 = _getLocalPositionFromTouch(touch1);
|
||||
final prevPos0 = _touchPositions[touch0.identifier];
|
||||
final prevPos1 = _touchPositions[touch1.identifier];
|
||||
|
||||
if (prevPos0 != null && prevPos1 != null) {
|
||||
final prevDist = (prevPos0 - prevPos1).length;
|
||||
final currDist = (pos0 - pos1).length;
|
||||
final scale = currDist / prevDist;
|
||||
final focalPoint = (pos0 + pos1) * 0.5;
|
||||
|
||||
inputHandler.onScaleUpdate(
|
||||
focalPoint,
|
||||
Vector2(0, 0),
|
||||
0.0,
|
||||
0.0,
|
||||
scale,
|
||||
touchCount,
|
||||
0.0,
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onTouchEnd(web.TouchEvent event) {
|
||||
for (var touch in event.changedTouches.toList()) {
|
||||
_touchPositions.remove(touch.identifier);
|
||||
}
|
||||
|
||||
final touchCount = event.touches.toList().length;
|
||||
inputHandler.onScaleEnd(touchCount, 0.0);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _onTouchCancel(web.TouchEvent event) {
|
||||
for (var touch in event.changedTouches.toList()) {
|
||||
_touchPositions.remove(touch.identifier);
|
||||
}
|
||||
|
||||
final touchCount = event.touches.toList().length;
|
||||
inputHandler.onScaleEnd(touchCount, 0.0);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
void _handleScaleStart(int pointerCount, Duration? sourceTimestamp) {
|
||||
inputHandler.onScaleStart(Vector2.zero(), pointerCount, sourceTimestamp);
|
||||
}
|
||||
|
||||
Vector2 _getLocalPositionFromEvent(web.Event event) {
|
||||
final rect = canvas.getBoundingClientRect();
|
||||
double clientX = 0, clientY = 0;
|
||||
|
||||
if (event is web.MouseEvent) {
|
||||
clientX = event.clientX.toDouble();
|
||||
clientY = event.clientY.toDouble();
|
||||
} else if (event is web.TouchEvent) {
|
||||
final touch = event.touches.toList().firstOrNull;
|
||||
if (touch != null) {
|
||||
clientX = touch.clientX;
|
||||
clientY = touch.clientY;
|
||||
}
|
||||
}
|
||||
|
||||
return Vector2(
|
||||
(clientX - rect.left) * pixelRatio,
|
||||
(clientY - rect.top) * pixelRatio,
|
||||
);
|
||||
}
|
||||
|
||||
Vector2 _getLocalPositionFromTouch(web.Touch touch) {
|
||||
final rect = canvas.getBoundingClientRect();
|
||||
return Vector2(
|
||||
(touch.clientX - rect.left) * pixelRatio,
|
||||
(touch.clientY - rect.top) * pixelRatio,
|
||||
);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
canvas.removeEventListener('mousedown', _onMouseDown.toJS);
|
||||
canvas.removeEventListener('mousemove', _onMouseMove.toJS);
|
||||
canvas.removeEventListener('mouseup', _onMouseUp.toJS);
|
||||
canvas.removeEventListener('wheel', _onMouseWheel.toJS);
|
||||
web.window.removeEventListener('keydown', _onKeyDown.toJS);
|
||||
web.window.removeEventListener('keyup', _onKeyUp.toJS);
|
||||
canvas.removeEventListener('touchstart', _onTouchStart.toJS);
|
||||
canvas.removeEventListener('touchmove', _onTouchMove.toJS);
|
||||
canvas.removeEventListener('touchend', _onTouchEnd.toJS);
|
||||
canvas.removeEventListener('touchcancel', _onTouchCancel.toJS);
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,6 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<!--
|
||||
If you are serving your web app in a path other than the root, change the
|
||||
href value below to reflect the base path you are serving from.
|
||||
|
||||
The path provided below has to start and end with a slash "/" in order for
|
||||
it to work correctly.
|
||||
|
||||
For more details:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||
|
||||
This is a placeholder for base href that will be replaced by the value of
|
||||
the `--base-href` argument provided to `flutter build`.
|
||||
-->
|
||||
<base href="$FLUTTER_BASE_HREF">
|
||||
|
||||
<meta charset="UTF-8">
|
||||
@@ -37,12 +24,17 @@
|
||||
const serviceWorkerVersion = null;
|
||||
</script>
|
||||
<script src="flutter.js" defer></script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="./thermion_dart.js"></script>
|
||||
<script type="module">
|
||||
try {
|
||||
window.thermion_dart = await thermion_dart();
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
<div id="flutter-container"></div>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('load', function (ev) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
../../../assets/thermion_dart.js
|
||||
../../../../thermion_dart/native/web/build/build/out/thermion_dart.js
|
||||
@@ -1 +1 @@
|
||||
../../../assets/thermion_dart.wasm
|
||||
../../../../thermion_dart/native/web/build/build/out/thermion_dart.wasm
|
||||
@@ -49,3 +49,67 @@ cmake --build . --target tinyexr --config Release
|
||||
cmake --build . --target imageio --config Release
|
||||
cmake --build . --config Debug
|
||||
```
|
||||
|
||||
# Web
|
||||
|
||||
By default, Filament WASM builds are single-threaded with no support for `-pthread` (`WEBGL_PTHREADS=0`).
|
||||
|
||||
This won't work with our current implementation, since at least `-pthread` is needed to support running Filament on a dedicated (non-main) render thread.
|
||||
|
||||
However, the multi-threaded Filament WASM build (`WEBGL_PTHREADS=1`, which sets `-pthread`) doesn't work with our current setup (which uses an OffscreenCanvas without proxying, effectively locking the context to a single thread).
|
||||
|
||||
To work around, we need to adjust the Filament build configuration to build:
|
||||
1) a single-threaded library
|
||||
2) but with `-pthread` enabled
|
||||
|
||||
|
||||
```
|
||||
./build.sh -p desktop release
|
||||
mkdir -p out/cmake-webgl-release
|
||||
cd out/cmake-webgl-release
|
||||
ln -s ../cmake-release/tools
|
||||
cmake -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWEBGL=1 \
|
||||
-DWEBGL_PTHREADS=1 \
|
||||
-DFILAMENT_SKIP_SAMPLES=1 \
|
||||
-DZLIB_INCLUDE_DIR=../../../../third_party/libz \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" \
|
||||
-DCMAKE_C_FLAGS="-pthread" \
|
||||
-DCMAKE_CXX_FLAGS="-pthread" \
|
||||
-DIS_HOST_PLATFORM=0 -DZ_HAVE_UNISTD_H=1 -DUSE_ZLIB=1 -DIMPORT_EXECUTABLES_DIR=out \
|
||||
../../
|
||||
ninja;
|
||||
mkdir imageio
|
||||
cd imageio
|
||||
cmake -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWEBGL=1 \
|
||||
-DWEBGL_PTHREADS=1 \
|
||||
-DFILAMENT_SKIP_SAMPLES=1 \
|
||||
-DZLIB_INCLUDE_DIR=../../../../third_party/libz \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" \
|
||||
-DCMAKE_C_FLAGS="-pthread" \
|
||||
-DCMAKE_CXX_FLAGS="-pthread" \
|
||||
-DZ_HAVE_UNISTD_H=1 -DUSE_ZLIB=1 -DIMPORT_EXECUTABLES_DIR=out -DCMAKE_CXX_FLAGS="-I../../../libs/image/include -I../../../libs/utils/include -I../../../libs/math/include -I../../../third_party/tinyexr -I../../../third_party/libpng -I../../../third_party/basisu/encoder" \
|
||||
../../../libs/imageio
|
||||
ninja
|
||||
cd ..
|
||||
mkdir thirdparty/
|
||||
cd thirdparty/
|
||||
#find . -type f -exec file {} \; | grep "text" | cut -d: -f1 | xargs dos2unix
|
||||
for lib in tinyexr libpng libz; do
|
||||
mkdir -p $lib;
|
||||
pushd $lib;
|
||||
cmake -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWEBGL=1 \
|
||||
-DWEBGL_PTHREADS=1 \
|
||||
-DFILAMENT_SKIP_SAMPLES=1 \
|
||||
-DZLIB_INCLUDE_DIR=../../../../third_party/libz \
|
||||
-DCMAKE_C_FLAGS="-pthread -Wno-reserved-identifier" \
|
||||
-DCMAKE_CXX_FLAGS="-pthread -Wno-reserved-identifier" \
|
||||
../../../../third_party/$lib;
|
||||
ninja;
|
||||
popd;
|
||||
done
|
||||
@@ -1,11 +1,9 @@
|
||||
output: '../lib/src/viewer/src/ffi/src/thermion_dart.g.dart'
|
||||
output: '../lib/src/bindings/src/thermion_dart_ffi.g.dart'
|
||||
headers:
|
||||
entry-points:
|
||||
- '../native/include/c_api/*.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
include-directives:
|
||||
- '../native/include/c_api/*.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
ffi-native:
|
||||
assetId: package:thermion_dart/thermion_dart.dart
|
||||
ignore-source-errors: true
|
||||
@@ -16,7 +14,4 @@ functions:
|
||||
enums:
|
||||
as-int:
|
||||
include:
|
||||
- TPrimitiveType
|
||||
- TPixelDataFormat
|
||||
- TPixelDataType
|
||||
|
||||
- .*
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
output: '../lib/thermion_dart/compatibility/web/thermion_dart.g.dart'
|
||||
output: '../lib/src/bindings/src/thermion_dart_js_interop.g.dart'
|
||||
headers:
|
||||
entry-points:
|
||||
- '../native/web/include/ThermionFlutterWebApi.h'
|
||||
- '../native/include/ThermionDartFFIApi.h'
|
||||
- '../native/include/ThermionDartApi.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
- '../native/web/include/ThermionWebApi.h'
|
||||
- '../native/include/c_api/*.h'
|
||||
include-directives:
|
||||
- '../native/web/include/ThermionFlutterWebApi.h'
|
||||
- '../native/include/ThermionDartFFIApi.h'
|
||||
- '../native/include/ThermionDartApi.h'
|
||||
- '../native/include/ResourceBuffer.h'
|
||||
- '../native/web/include/ThermionWebApi.h'
|
||||
- '../native/include/c_api/*.h'
|
||||
compiler-opts:
|
||||
- "-D__EMSCRIPTEN__"
|
||||
structs:
|
||||
@@ -20,9 +16,8 @@ unions:
|
||||
dependency-only: opaque
|
||||
exclude:
|
||||
- '.*'
|
||||
globals:
|
||||
exclude:
|
||||
- '.*'
|
||||
ffi-native:
|
||||
assetId: thermion_dart
|
||||
ignore-source-errors: true
|
||||
enums:
|
||||
as-int:
|
||||
include:
|
||||
- .*
|
||||
@@ -1,8 +1,9 @@
|
||||
import 'dart:io';
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:code_assets/code_assets.dart';
|
||||
import 'package:hooks/hooks.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:native_assets_cli/code_assets_builder.dart';
|
||||
import 'package:native_assets_cli/native_assets_cli.dart';
|
||||
|
||||
import 'package:native_toolchain_c/native_toolchain_c.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
@@ -25,6 +26,7 @@ void main(List<String> args) async {
|
||||
final packageName = input.packageName;
|
||||
final outputDirectory = input.outputDirectory;
|
||||
final targetOS = config.code.targetOS;
|
||||
|
||||
final targetArchitecture = config.code.targetArchitecture;
|
||||
var logPath = path.join(
|
||||
pkgRootFilePath, ".dart_tool", "thermion_dart", "log", "build.log");
|
||||
@@ -258,9 +260,8 @@ void main(List<String> args) async {
|
||||
package: "thermion_dart",
|
||||
name: "libc++_shared.so",
|
||||
linkMode: DynamicLoadingBundled(),
|
||||
os: targetOS,
|
||||
file: stlPath.uri,
|
||||
architecture: targetArchitecture);
|
||||
);
|
||||
|
||||
output.assets.addEncodedAsset(libcpp.encode());
|
||||
}
|
||||
@@ -274,9 +275,8 @@ void main(List<String> args) async {
|
||||
package: packageName,
|
||||
name: "thermion_dart.lib",
|
||||
linkMode: DynamicLoadingBundled(),
|
||||
os: targetOS,
|
||||
file: importLib.uri,
|
||||
architecture: targetArchitecture);
|
||||
);
|
||||
output.assets.addEncodedAsset(libthermion.encode());
|
||||
|
||||
for (final dir in ["windows/vulkan"]) {
|
||||
@@ -298,9 +298,8 @@ void main(List<String> args) async {
|
||||
package: packageName,
|
||||
name: "include/$dir/${path.basename(file.path)}",
|
||||
linkMode: DynamicLoadingBundled(),
|
||||
os: targetOS,
|
||||
file: file.uri,
|
||||
architecture: targetArchitecture);
|
||||
);
|
||||
output.assets.addEncodedAsset(include.encode());
|
||||
}
|
||||
}
|
||||
|
||||
3
thermion_dart/lib/src/bindings/bindings.dart
Normal file
3
thermion_dart/lib/src/bindings/bindings.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
export 'src/ffi.dart'
|
||||
if (dart.library.io) 'src/ffi.dart'
|
||||
if (dart.library.js_interop) 'src/js_interop.dart';
|
||||
@@ -1,29 +1,89 @@
|
||||
export 'thermion_dart_ffi.g.dart';
|
||||
|
||||
export 'dart:typed_data';
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'dart:io';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
export 'package:ffi/ffi.dart';
|
||||
export 'dart:ffi';
|
||||
export 'thermion_dart.g.dart';
|
||||
export 'dart:ffi' hide Size;
|
||||
|
||||
final allocator = calloc;
|
||||
const FILAMENT_SINGLE_THREADED = false;
|
||||
const FILAMENT_WASM = false;
|
||||
bool get IS_WINDOWS => Platform.isWindows;
|
||||
|
||||
void using(Pointer ptr, Future Function(Pointer ptr) function) async {
|
||||
await function.call(ptr);
|
||||
allocator.free(ptr);
|
||||
class NativeLibrary {
|
||||
static void initBindings(String name) {
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> withVoidCallback2(Function() func) async {
|
||||
final completer = Completer();
|
||||
void Function() callback = () {
|
||||
func.call();
|
||||
completer.complete();
|
||||
};
|
||||
final nativeCallable = NativeCallable<Void Function()>.listener(callback);
|
||||
RenderThread_addTask(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
nativeCallable.close();
|
||||
typedef IntPtrList = Int64List;
|
||||
typedef Float64 = Double;
|
||||
typedef PointerClass<T extends NativeType> = Pointer<T>;
|
||||
typedef VoidPointerClass = Pointer<Void>;
|
||||
|
||||
class CallbackHolder<T extends Function> {
|
||||
final NativeCallable<T> nativeCallable;
|
||||
|
||||
Pointer<NativeFunction<T>> get pointer => nativeCallable.nativeFunction;
|
||||
|
||||
CallbackHolder(this.nativeCallable);
|
||||
|
||||
void dispose() {
|
||||
nativeCallable.close();
|
||||
}
|
||||
}
|
||||
|
||||
Pointer<T> allocate<T extends NativeType>(int count) {
|
||||
return calloc.allocate<T>(count * sizeOf<Pointer>());
|
||||
}
|
||||
|
||||
void free(Pointer ptr) {
|
||||
calloc.free(ptr);
|
||||
}
|
||||
|
||||
Pointer stackSave() {
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
void stackRestore(Pointer ptr) {
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
class FinalizableUint8List implements Finalizable {
|
||||
final Pointer name;
|
||||
final Uint8List data;
|
||||
|
||||
FinalizableUint8List(this.name, this.data);
|
||||
}
|
||||
|
||||
extension GPFBP on void Function(int, double, double, double) {
|
||||
CallbackHolder<GizmoPickCallbackFunction> asCallback() {
|
||||
var nativeCallable =
|
||||
NativeCallable<GizmoPickCallbackFunction>.listener(this);
|
||||
return CallbackHolder(nativeCallable);
|
||||
}
|
||||
}
|
||||
|
||||
CallbackHolder<PickCallbackFunction> makePickCallbackFunctionPointer(
|
||||
DartPickCallbackFunction fn) {
|
||||
final nc = NativeCallable<PickCallbackFunction>.listener(fn);
|
||||
final cbh = CallbackHolder(nc);
|
||||
return cbh;
|
||||
}
|
||||
|
||||
extension VFB on void Function() {
|
||||
CallbackHolder<Void Function()> asCallback() {
|
||||
var nativeCallable = NativeCallable<Void Function()>.listener(this);
|
||||
return CallbackHolder(nativeCallable);
|
||||
}
|
||||
}
|
||||
|
||||
extension PCBF on DartPickCallbackFunction {
|
||||
CallbackHolder<PickCallbackFunction> asCallback() {
|
||||
var nativeCallable = NativeCallable<PickCallbackFunction>.listener(this);
|
||||
return CallbackHolder(nativeCallable);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> withVoidCallback(
|
||||
@@ -75,7 +135,8 @@ Future<double> withFloatCallback(
|
||||
void Function(double) callback = (double result) {
|
||||
completer.complete(result);
|
||||
};
|
||||
final nativeCallable = NativeCallable<Void Function(Float)>.listener(callback);
|
||||
final nativeCallable =
|
||||
NativeCallable<Void Function(Float)>.listener(callback);
|
||||
func.call(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
nativeCallable.close();
|
||||
@@ -127,3 +188,15 @@ Future<String> withCharPtrCallback(
|
||||
nativeCallable.close();
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
extension FreeTypedData<T> on TypedData {
|
||||
void free() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
extension DartBigIntExtension on int {
|
||||
int get toBigInt {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
408
thermion_dart/lib/src/bindings/src/js_interop.dart
Normal file
408
thermion_dart/lib/src/bindings/src/js_interop.dart
Normal file
@@ -0,0 +1,408 @@
|
||||
import 'dart:async';
|
||||
export 'dart:typed_data';
|
||||
|
||||
export 'thermion_dart_js_interop.g.dart';
|
||||
export 'dart:js_interop';
|
||||
export 'dart:js_interop_unsafe';
|
||||
import 'package:thermion_dart/src/bindings/src/js_interop.dart';
|
||||
|
||||
const FILAMENT_SINGLE_THREADED = true;
|
||||
const FILAMENT_WASM = true;
|
||||
const IS_WINDOWS = false;
|
||||
|
||||
extension type _NativeLibrary(JSObject _) implements JSObject {
|
||||
static _NativeLibrary get instance =>
|
||||
NativeLibrary.instance as _NativeLibrary;
|
||||
|
||||
external JSUint8Array _emscripten_make_uint8_buffer(
|
||||
Pointer<Uint8> ptr, int length);
|
||||
external JSUint16Array _emscripten_make_uint16_buffer(
|
||||
Pointer<Uint16> ptr, int length);
|
||||
external JSInt16Array _emscripten_make_int16_buffer(
|
||||
Pointer<Int16> ptr, int length);
|
||||
external JSInt32Array _emscripten_make_int32_buffer(
|
||||
Pointer<Int32> ptr, int length);
|
||||
external JSFloat32Array _emscripten_make_f32_buffer(
|
||||
Pointer<Float32> ptr, int length);
|
||||
external JSFloat64Array _emscripten_make_f64_buffer(
|
||||
Pointer<Float64> ptr, int length);
|
||||
external Pointer _emscripten_get_byte_offset(JSObject obj);
|
||||
|
||||
external int _emscripten_stack_get_free();
|
||||
|
||||
external void _execute_queue();
|
||||
|
||||
@JS('stackSave')
|
||||
external Pointer<Void> stackSave();
|
||||
|
||||
@JS('stackRestore')
|
||||
external void stackRestore(Pointer<Void> ptr);
|
||||
}
|
||||
|
||||
extension FreeTypedData<T> on TypedData {
|
||||
void free() {
|
||||
final ptr = Pointer<Void>(this.offsetInBytes);
|
||||
ptr.free();
|
||||
}
|
||||
}
|
||||
|
||||
Pointer<T> getPointer<T extends NativeType>(TypedData data, JSObject obj) {
|
||||
late Pointer<T> ptr;
|
||||
|
||||
if (data.lengthInBytes < 32 * 1024) {
|
||||
ptr = stackAlloc(data.lengthInBytes).cast<T>();
|
||||
} else {
|
||||
ptr = malloc<T>(data.lengthInBytes);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
extension JSBackingBuffer on JSUint8Array {
|
||||
@JS('buffer')
|
||||
external JSObject buffer;
|
||||
}
|
||||
|
||||
@JS('Uint8Array')
|
||||
extension type Uint8ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Uint8ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
@JS('Int8Array')
|
||||
extension type Int8ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Int8ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
@JS('Uint16Array')
|
||||
extension type Uint16ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Uint16ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
@JS('Int16Array')
|
||||
extension type Int16ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Int16ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
@JS('Uint32Array')
|
||||
extension type Uint32ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Uint32ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
@JS('Int32Array')
|
||||
extension type Int32ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Int32ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
@JS('Float32Array')
|
||||
extension type Float32ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Float32ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
@JS('Float64Array')
|
||||
extension type Float64ArrayWrapper._(JSObject _) implements JSObject {
|
||||
external Float64ArrayWrapper(JSObject buffer, int offset, int length);
|
||||
}
|
||||
|
||||
extension Uint8ListExtension on Uint8List {
|
||||
Pointer<Uint8> get address {
|
||||
if (this.lengthInBytes == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
final ptr = getPointer<Uint8>(this, this.toJS);
|
||||
final bar =
|
||||
Uint8ArrayWrapper(NativeLibrary.instance.HEAPU8.buffer, ptr, length)
|
||||
as JSUint8Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
extension Float32ListExtension on Float32List {
|
||||
Pointer<Float32> get address {
|
||||
final ptr = getPointer<Float32>(this, this.toJS);
|
||||
final bar =
|
||||
Float32ArrayWrapper(NativeLibrary.instance.HEAPU8.buffer, ptr, length)
|
||||
as JSFloat32Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
extension Int16ListExtension on Int16List {
|
||||
Pointer<Int16> get address {
|
||||
if (this.lengthInBytes == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
final ptr = getPointer<Int16>(this, this.toJS);
|
||||
final bar = Int16ArrayWrapper(NativeLibrary.instance.HEAPU8, ptr, length)
|
||||
as JSInt16Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
extension Uint16ListExtension on Uint16List {
|
||||
Pointer<Uint16> get address {
|
||||
final ptr = getPointer<Uint16>(this, this.toJS);
|
||||
final bar =
|
||||
Uint16ArrayWrapper(NativeLibrary.instance.HEAPU8.buffer, ptr, length)
|
||||
as JSUint16Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt32ListExtension on Uint32List {
|
||||
Pointer<Uint32> get address {
|
||||
if (this.lengthInBytes == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
final ptr = getPointer<Uint32>(this, this.toJS);
|
||||
final bar = Uint32ArrayWrapper(NativeLibrary.instance.HEAPU8, ptr, length)
|
||||
as JSUint32Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
extension Int32ListExtension on Int32List {
|
||||
Pointer<Int32> get address {
|
||||
if (this.lengthInBytes == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
final ptr = getPointer<Int32>(this, this.toJS);
|
||||
final bar = Int32ArrayWrapper(NativeLibrary.instance.HEAPU8, ptr, length)
|
||||
as JSInt32Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
extension Int64ListExtension on Int64List {
|
||||
Pointer<Float32> get address {
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
static Int64List create(int length) {
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
|
||||
extension Float64ListExtension on Float64List {
|
||||
Pointer<Float64> get address {
|
||||
if (this.lengthInBytes == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
final ptr = getPointer<Float64>(this, this.toJS);
|
||||
final bar =
|
||||
Float64ArrayWrapper(NativeLibrary.instance.HEAPU8.buffer, ptr, length)
|
||||
as JSFloat64Array;
|
||||
bar.toDart.setRange(0, length, this);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// static Float64List create(int length) {
|
||||
// final ptr = malloc(length * 8);
|
||||
// final buffer = _NativeLibrary.instance._emscripten_make_f64_buffer(ptr.cast(), length).toDart;
|
||||
// _allocated.add(buffer);
|
||||
// return buffer;
|
||||
// }
|
||||
}
|
||||
|
||||
int sizeOf<T extends NativeType>() {
|
||||
switch (T) {
|
||||
case Float:
|
||||
return 4;
|
||||
default:
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
|
||||
typedef IntPtrList = Int32List;
|
||||
typedef Utf8 = Char;
|
||||
typedef Float = Float32;
|
||||
typedef Double = Float64;
|
||||
typedef Bool = bool;
|
||||
|
||||
class FinalizableUint8List {
|
||||
final Pointer name;
|
||||
final Uint8List data;
|
||||
|
||||
FinalizableUint8List(this.name, this.data);
|
||||
}
|
||||
|
||||
class CallbackHolder<T extends Function> {
|
||||
final Pointer<NativeFunction<T>> pointer;
|
||||
|
||||
CallbackHolder(this.pointer);
|
||||
|
||||
void dispose() {
|
||||
pointer.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
extension DPCF on DartPickCallbackFunction {
|
||||
CallbackHolder<DartPickCallbackFunction> asCallback() {
|
||||
final ptr = addFunction<DartPickCallbackFunction>(this.toJS, "viidddd");
|
||||
final cbh = CallbackHolder(ptr);
|
||||
return cbh;
|
||||
}
|
||||
}
|
||||
|
||||
extension GPFBP on void Function(int, double, double, double) {
|
||||
CallbackHolder<GizmoPickCallbackFunction> asCallback() {
|
||||
final ptr = addFunction<GizmoPickCallbackFunction>(this.toJS, "viddd");
|
||||
return CallbackHolder(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
extension VFCB on void Function() {
|
||||
CallbackHolder<void Function()> asCallback() {
|
||||
final ptr = addFunction<void Function()>(this.toJS, "v");
|
||||
return CallbackHolder(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
final _completers = <int, Completer>{};
|
||||
void Function(int) _voidCallback = (int requestId) {
|
||||
_completers[requestId]!.complete();
|
||||
_completers.remove(requestId);
|
||||
};
|
||||
|
||||
final _voidCallbackPtr = _voidCallback.addFunction();
|
||||
|
||||
Future<void> withVoidCallback(
|
||||
Function(Pointer<NativeFunction<Void Function()>>) func) async {
|
||||
final completer = Completer();
|
||||
final requestId = _completers.length;
|
||||
_completers[requestId] = completer;
|
||||
|
||||
final fn = () {
|
||||
completer.complete();
|
||||
};
|
||||
|
||||
final ptr = fn.addFunction();
|
||||
|
||||
func.call(ptr.cast());
|
||||
while (!completer.isCompleted) {
|
||||
_NativeLibrary.instance._execute_queue();
|
||||
await Future.delayed(Duration(milliseconds: 1));
|
||||
}
|
||||
await completer.future;
|
||||
}
|
||||
|
||||
Future<Pointer<T>> withPointerCallback<T extends NativeType>(
|
||||
Function(Pointer<NativeFunction<Void Function(Pointer<T>)>>) func) async {
|
||||
final completer = Completer<Pointer<T>>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function(Pointer<T>) callback = (Pointer<T> ptr) {
|
||||
completer.complete(ptr.cast<T>());
|
||||
};
|
||||
|
||||
final onComplete_interopFnPtr = callback.addFunction();
|
||||
|
||||
func.call(onComplete_interopFnPtr.cast());
|
||||
|
||||
var ptr = await completer.future;
|
||||
onComplete_interopFnPtr.dispose();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Future<bool> withBoolCallback(
|
||||
Function(Pointer<NativeFunction<Void Function(Bool)>>) func) async {
|
||||
final completer = Completer<bool>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function(int) callback = (int result) {
|
||||
completer.complete(result == 1);
|
||||
};
|
||||
|
||||
final onComplete_interopFnPtr = callback.addFunction();
|
||||
|
||||
func.call(onComplete_interopFnPtr.cast());
|
||||
await completer.future;
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<double> withFloatCallback(
|
||||
void Function(Pointer<NativeFunction<void Function(double)>>) func) async {
|
||||
final completer = Completer<double>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function(double) callback = (double result) {
|
||||
completer.complete(result);
|
||||
};
|
||||
var ptr = callback.addFunction();
|
||||
func.call(ptr);
|
||||
await completer.future;
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<int> withIntCallback(
|
||||
Function(Pointer<NativeFunction<Void Function(Int32)>>) func) async {
|
||||
final completer = Completer<int>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function(int) callback = (int result) {
|
||||
completer.complete(result);
|
||||
};
|
||||
// final nativeCallable =
|
||||
// NativeCallable<Void Function(Int32)>.listener(callback);
|
||||
// func.call(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
// nativeCallable.close();
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Pointer<T> allocate<T extends NativeType>(int count) {
|
||||
switch (T) {
|
||||
case PointerClass:
|
||||
return malloc(count * 4);
|
||||
default:
|
||||
throw Exception(T.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<int> withUInt32Callback(
|
||||
Function(Pointer<NativeFunction<Void Function(int)>>) func) async {
|
||||
final completer = Completer<int>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function(int) callback = (int result) {
|
||||
completer.complete(result);
|
||||
};
|
||||
// final nativeCallable =
|
||||
// NativeCallable<Void Function(Uint32)>.listener(callback);
|
||||
// func.call(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
// nativeCallable.close();
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<String> withCharPtrCallback(
|
||||
Function(Pointer<NativeFunction<Void Function(Pointer<Char>)>>)
|
||||
func) async {
|
||||
final completer = Completer<String>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
// void Function(Pointer<Char>) callback = (Pointer<Char> result) {
|
||||
// completer.complete(result.cast<Utf8>().toDartString());
|
||||
// };
|
||||
// final nativeCallable =
|
||||
// NativeCallable<Void Function(Pointer<Char>)>.listener(callback);
|
||||
// func.call(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
// nativeCallable.close();
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
extension DartBigIntExtension on int {
|
||||
BigInt get toBigInt {
|
||||
return BigInt.from(this);
|
||||
}
|
||||
}
|
||||
|
||||
Pointer stackSave() => _NativeLibrary.instance.stackSave();
|
||||
|
||||
void stackRestore(Pointer ptr) =>
|
||||
_NativeLibrary.instance.stackRestore(ptr.cast());
|
||||
|
||||
void getStackFree() {
|
||||
print(_NativeLibrary.instance._emscripten_stack_get_free());
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
6834
thermion_dart/lib/src/bindings/src/thermion_dart_js_interop.g.dart
Normal file
6834
thermion_dart/lib/src/bindings/src/thermion_dart_js_interop.g.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
export 'src/filament_app.dart';
|
||||
export 'src/engine.dart';
|
||||
export 'src/layers.dart';
|
||||
export 'src/light_options.dart';
|
||||
export 'src/interface/filament_app.dart';
|
||||
export 'src/interface/engine.dart';
|
||||
export 'src/interface/layers.dart';
|
||||
export 'src/interface/light_options.dart';
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../../viewer/viewer.dart';
|
||||
|
||||
class Geometry {
|
||||
final Float32List vertices;
|
||||
final Uint16List indices;
|
||||
final Float32List normals;
|
||||
final Float32List uvs;
|
||||
final PrimitiveType primitiveType;
|
||||
|
||||
Geometry(
|
||||
this.vertices,
|
||||
List<int> indices, {
|
||||
Float32List? normals,
|
||||
Float32List? uvs,
|
||||
this.primitiveType = PrimitiveType.TRIANGLES,
|
||||
}) : indices = Uint16List.fromList(indices),
|
||||
normals = normals ?? Float32List(0),
|
||||
uvs = uvs ?? Float32List(0) {
|
||||
assert(this.uvs.length == 0 || this.uvs.length == (vertices.length ~/ 3 * 2), "Expected either zero or ${indices.length * 2} UVs, got ${this.uvs.length}");
|
||||
}
|
||||
|
||||
void scale(double factor) {
|
||||
for (int i = 0; i < vertices.length; i++) {
|
||||
vertices[i] = vertices[i] * factor;
|
||||
}
|
||||
}
|
||||
|
||||
bool get hasNormals => normals.isNotEmpty;
|
||||
bool get hasUVs => uvs.isNotEmpty;
|
||||
}
|
||||
@@ -2,11 +2,11 @@ import 'dart:typed_data';
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
import 'package:animation_tools_dart/src/bone_animation_data.dart';
|
||||
import 'package:animation_tools_dart/src/morph_animation_data.dart';
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/layers.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class BackgroundImage extends ThermionAsset {
|
||||
@@ -47,10 +47,12 @@ class BackgroundImage extends ThermionAsset {
|
||||
var backgroundImage =
|
||||
await viewer.createGeometry(GeometryHelper.fullscreenQuad());
|
||||
await imageMaterialInstance.setParameterInt("showImage", 0);
|
||||
await imageMaterialInstance.setParameterMat4(
|
||||
"transform", Matrix4.identity());
|
||||
var transform = Matrix4.identity();
|
||||
|
||||
backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
||||
await imageMaterialInstance.setParameterMat4(
|
||||
"transform", transform);
|
||||
|
||||
await backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
||||
await scene.add(backgroundImage as FFIAsset);
|
||||
return BackgroundImage._(
|
||||
backgroundImage, scene, null, null, imageMaterialInstance);
|
||||
@@ -1,13 +1,8 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/utils/src/matrix.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_material.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
|
||||
@@ -52,15 +47,31 @@ class FFIAsset extends ThermionAsset {
|
||||
entity = SceneAsset_getEntity(asset);
|
||||
}
|
||||
|
||||
Int32List? _childEntities;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<List<ThermionEntity>> getChildEntities() async {
|
||||
var count = SceneAsset_getChildEntityCount(asset);
|
||||
var children = Int32List(count);
|
||||
SceneAsset_getChildEntities(asset, children.address);
|
||||
return children;
|
||||
if (_childEntities == null) {
|
||||
var count = SceneAsset_getChildEntityCount(asset);
|
||||
var childEntities = Int32List(count);
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
if (count > 0) {
|
||||
SceneAsset_getChildEntities(asset, childEntities.address);
|
||||
}
|
||||
_childEntities = Int32List.fromList(childEntities);
|
||||
childEntities.free();
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
}
|
||||
|
||||
return _childEntities!;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -118,24 +129,32 @@ class FFIAsset extends ThermionAsset {
|
||||
@override
|
||||
Future<FFIAsset> createInstance(
|
||||
{covariant List<MaterialInstance>? materialInstances = null}) async {
|
||||
var created = await withPointerCallback<TSceneAsset>((cb) {
|
||||
var ptrList = Int64List(materialInstances?.length ?? 0);
|
||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
||||
ptrList.setRange(
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<FFIMaterialInstance>()
|
||||
.map((mi) => mi.pointer.address)
|
||||
.toList());
|
||||
}
|
||||
var ptrList = IntPtrList(materialInstances?.length ?? 0);
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
|
||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
||||
ptrList.setRange(
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<FFIMaterialInstance>()
|
||||
.map((mi) => mi.pointer.address)
|
||||
.toList());
|
||||
}
|
||||
|
||||
var created = await withPointerCallback<TSceneAsset>((cb) {
|
||||
SceneAsset_createInstanceRenderThread(
|
||||
asset,
|
||||
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
||||
materialInstances?.length ?? 0,
|
||||
cb);
|
||||
asset, ptrList.address.cast(), materialInstances?.length ?? 0, cb);
|
||||
});
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
ptrList.free();
|
||||
}
|
||||
|
||||
if (created == FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("Failed to create instance");
|
||||
}
|
||||
@@ -251,6 +270,13 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
ThermionAsset? boundingBoxAsset;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future dispose() async {
|
||||
_childEntities?.free();
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -326,14 +352,14 @@ class FFIAsset extends ThermionAsset {
|
||||
vertices[23] = max[2]; // v7
|
||||
|
||||
// Indices for lines (24 indices for 12 lines)
|
||||
final indices = [
|
||||
final indices = Uint16List.fromList([
|
||||
// Bottom face
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
// Top face
|
||||
4, 5, 5, 6, 6, 7, 7, 4,
|
||||
// Vertical edges
|
||||
0, 4, 1, 5, 2, 6, 3, 7
|
||||
];
|
||||
]);
|
||||
|
||||
// Create unlit material instance for the wireframe
|
||||
final materialInstancePtr =
|
||||
@@ -366,6 +392,10 @@ class FFIAsset extends ThermionAsset {
|
||||
|
||||
TransformManager_setParent(Engine_getTransformManager(app.engine),
|
||||
boundingBoxAsset!.entity, entity, false);
|
||||
geometry.uvs?.free();
|
||||
geometry.normals?.free();
|
||||
geometry.vertices.free();
|
||||
geometry.indices.free();
|
||||
}
|
||||
return boundingBoxAsset!;
|
||||
}
|
||||
@@ -461,7 +491,7 @@ class FFIAsset extends ThermionAsset {
|
||||
if (weights.isEmpty) {
|
||||
throw Exception("Weights must not be empty");
|
||||
}
|
||||
var weightsPtr = allocator<Float>(weights.length);
|
||||
var weightsPtr = allocate<Float>(weights.length);
|
||||
|
||||
for (int i = 0; i < weights.length; i++) {
|
||||
weightsPtr[i] = weights[i];
|
||||
@@ -470,7 +500,7 @@ class FFIAsset extends ThermionAsset {
|
||||
AnimationManager_setMorphTargetWeightsRenderThread(
|
||||
animationManager, entity, weightsPtr, weights.length, cb);
|
||||
});
|
||||
allocator.free(weightsPtr);
|
||||
free(weightsPtr);
|
||||
|
||||
if (!success) {
|
||||
throw Exception(
|
||||
@@ -489,13 +519,13 @@ class FFIAsset extends ThermionAsset {
|
||||
|
||||
var count = AnimationManager_getMorphTargetNameCount(
|
||||
animationManager, asset, entity);
|
||||
var outPtr = allocator<Char>(255);
|
||||
var outPtr = allocate<Char>(255);
|
||||
for (int i = 0; i < count; i++) {
|
||||
AnimationManager_getMorphTargetName(
|
||||
animationManager, asset, entity, outPtr, i);
|
||||
names.add(outPtr.cast<Utf8>().toDartString());
|
||||
}
|
||||
allocator.free(outPtr);
|
||||
free(outPtr);
|
||||
return names.cast<String>();
|
||||
}
|
||||
|
||||
@@ -505,9 +535,9 @@ class FFIAsset extends ThermionAsset {
|
||||
Future<List<String>> getBoneNames({int skinIndex = 0}) async {
|
||||
var count =
|
||||
AnimationManager_getBoneCount(animationManager, asset, skinIndex);
|
||||
var out = allocator<Pointer<Char>>(count);
|
||||
var out = allocate<PointerClass<Char>>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
out[i] = allocator<Char>(255);
|
||||
out[i] = allocate<Char>(255);
|
||||
}
|
||||
|
||||
AnimationManager_getBoneNames(animationManager, asset, out, skinIndex);
|
||||
@@ -516,6 +546,10 @@ class FFIAsset extends ThermionAsset {
|
||||
var namePtr = out[i];
|
||||
names.add(namePtr.cast<Utf8>().toDartString());
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
free(out[i]);
|
||||
}
|
||||
free(out);
|
||||
return names;
|
||||
}
|
||||
|
||||
@@ -527,12 +561,12 @@ class FFIAsset extends ThermionAsset {
|
||||
var animationCount =
|
||||
AnimationManager_getAnimationCount(animationManager, asset);
|
||||
var names = <String>[];
|
||||
var outPtr = allocator<Char>(255);
|
||||
var outPtr = allocate<Char>(255);
|
||||
for (int i = 0; i < animationCount; i++) {
|
||||
AnimationManager_getAnimationName(animationManager, asset, outPtr, i);
|
||||
names.add(outPtr.cast<Utf8>().toDartString());
|
||||
}
|
||||
allocator.free(outPtr);
|
||||
free(outPtr);
|
||||
|
||||
return names;
|
||||
}
|
||||
@@ -636,6 +670,9 @@ class FFIAsset extends ThermionAsset {
|
||||
animation.numFrames,
|
||||
animation.frameLengthInMs);
|
||||
|
||||
frameData.data.free();
|
||||
indices.free();
|
||||
|
||||
if (!result) {
|
||||
throw Exception("Failed to set morph animation data for ${meshName}");
|
||||
}
|
||||
@@ -659,7 +696,7 @@ class FFIAsset extends ThermionAsset {
|
||||
throw UnimplementedError("TODO - support skinIndex != 0 ");
|
||||
}
|
||||
var boneNames = await getBoneNames();
|
||||
var restLocalTransformsRaw = allocator<Float>(boneNames.length * 16);
|
||||
var restLocalTransformsRaw = allocate<Float>(boneNames.length * 16);
|
||||
AnimationManager_getRestLocalTransforms(animationManager, asset, skinIndex,
|
||||
restLocalTransformsRaw, boneNames.length);
|
||||
|
||||
@@ -671,11 +708,11 @@ class FFIAsset extends ThermionAsset {
|
||||
}
|
||||
restLocalTransforms.add(Matrix4.fromList(values));
|
||||
}
|
||||
allocator.free(restLocalTransformsRaw);
|
||||
free(restLocalTransformsRaw);
|
||||
|
||||
var numFrames = animation.frameData.length;
|
||||
|
||||
var data = allocator<Float>(numFrames * 16);
|
||||
var data = allocate<Float>(numFrames * 16);
|
||||
|
||||
var bones = await Future.wait(List<Future<ThermionEntity>>.generate(
|
||||
boneNames.length, (i) => getBone(i)));
|
||||
@@ -720,8 +757,7 @@ class FFIAsset extends ThermionAsset {
|
||||
baseTransform * (worldInverse * frameTransform * world);
|
||||
}
|
||||
for (int j = 0; j < 16; j++) {
|
||||
data.elementAt((frameNum * 16) + j).value =
|
||||
newLocalTransform.storage[j];
|
||||
data[(frameNum * 16) + j] = newLocalTransform.storage[j];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,25 +773,41 @@ class FFIAsset extends ThermionAsset {
|
||||
fadeInInSecs,
|
||||
maxDelta);
|
||||
}
|
||||
allocator.free(data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Matrix4> getLocalTransform({ThermionEntity? entity}) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
entity ??= this.entity;
|
||||
return double4x4ToMatrix4(
|
||||
final transform = double4x4ToMatrix4(
|
||||
TransformManager_getLocalTransform(app.transformManager, entity));
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Matrix4> getWorldTransform({ThermionEntity? entity}) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
entity ??= this.entity;
|
||||
return double4x4ToMatrix4(
|
||||
var transform = double4x4ToMatrix4(
|
||||
TransformManager_getWorldTransform(app.transformManager, entity));
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -786,10 +838,19 @@ class FFIAsset extends ThermionAsset {
|
||||
///
|
||||
Future<Matrix4> getInverseBindMatrix(int boneIndex,
|
||||
{int skinIndex = 0}) async {
|
||||
var matrix = Float32List(16);
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var matrixIn = Float32List(16);
|
||||
AnimationManager_getInverseBindMatrix(
|
||||
animationManager, asset, skinIndex, boneIndex, matrix.address);
|
||||
return Matrix4.fromList(matrix);
|
||||
animationManager, asset, skinIndex, boneIndex, matrixIn.address);
|
||||
var matrixOut = Matrix4.fromList(matrixIn);
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
matrixIn.free();
|
||||
}
|
||||
return matrixOut;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -813,7 +874,7 @@ class FFIAsset extends ThermionAsset {
|
||||
if (skinIndex != 0) {
|
||||
throw UnimplementedError("TOOD");
|
||||
}
|
||||
final ptr = allocator<Float>(16);
|
||||
final ptr = allocate<Float>(16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
ptr[i] = transform.storage[i];
|
||||
}
|
||||
@@ -822,7 +883,7 @@ class FFIAsset extends ThermionAsset {
|
||||
animationManager, entity, skinIndex, boneIndex, ptr, cb);
|
||||
});
|
||||
|
||||
allocator.free(ptr);
|
||||
free(ptr);
|
||||
if (!result) {
|
||||
throw Exception("Failed to set bone transform");
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
import '../../../../utils/src/matrix.dart';
|
||||
import '../../../utils/src/matrix.dart';
|
||||
|
||||
class FFICamera extends Camera {
|
||||
final Pointer<TCamera> camera;
|
||||
@@ -31,7 +26,15 @@ class FFICamera extends Camera {
|
||||
///
|
||||
///
|
||||
Future<Matrix4> getModelMatrix() async {
|
||||
return double4x4ToMatrix4(Camera_getModelMatrix(camera));
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
stackPtr = stackSave();
|
||||
}
|
||||
final modelMatrix = double4x4ToMatrix4(Camera_getModelMatrix(camera));
|
||||
if (FILAMENT_WASM) {
|
||||
stackRestore(stackPtr);
|
||||
}
|
||||
return modelMatrix;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -39,8 +42,16 @@ class FFICamera extends Camera {
|
||||
///
|
||||
@override
|
||||
Future<Matrix4> getProjectionMatrix() async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var matrixStruct = Camera_getProjectionMatrix(camera);
|
||||
return double4x4ToMatrix4(matrixStruct);
|
||||
final pMat = double4x4ToMatrix4(matrixStruct);
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
return pMat;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -48,8 +59,17 @@ class FFICamera extends Camera {
|
||||
///
|
||||
@override
|
||||
Future<Matrix4> getCullingProjectionMatrix() async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var matrixStruct = Camera_getCullingProjectionMatrix(camera);
|
||||
return double4x4ToMatrix4(matrixStruct);
|
||||
final cpMat = double4x4ToMatrix4(matrixStruct);
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
return cpMat;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -81,7 +101,15 @@ class FFICamera extends Camera {
|
||||
///
|
||||
@override
|
||||
Future setModelMatrix(Matrix4 matrix) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
stackPtr = stackSave();
|
||||
}
|
||||
Camera_setModelMatrix(camera, matrix.storage.address);
|
||||
if (FILAMENT_WASM) {
|
||||
stackRestore(stackPtr);
|
||||
matrix.storage.free();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -122,6 +150,10 @@ class FFICamera extends Camera {
|
||||
///
|
||||
///
|
||||
Future<Frustum> getFrustum() async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var out = Float64List(24);
|
||||
Camera_getFrustum(camera, out.address);
|
||||
|
||||
@@ -132,19 +164,31 @@ class FFICamera extends Camera {
|
||||
frustum.plane3.setFromComponents(out[12], out[13], out[14], out[15]);
|
||||
frustum.plane4.setFromComponents(out[16], out[17], out[18], out[19]);
|
||||
frustum.plane5.setFromComponents(out[20], out[21], out[22], out[23]);
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
out.free();
|
||||
}
|
||||
return frustum;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getViewMatrix() async {
|
||||
return double4x4ToMatrix4(Camera_getViewMatrix(camera));
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
final matrix = double4x4ToMatrix4(Camera_getViewMatrix(camera));
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@override
|
||||
Future setProjection(Projection projection, double left, double right,
|
||||
double bottom, double top, double near, double far) async {
|
||||
Camera_setProjection(camera, TProjection.values[projection.index], left,
|
||||
right, bottom, top, near, far);
|
||||
Camera_setProjection(
|
||||
camera, projection.index, left, right, bottom, top, near, far);
|
||||
}
|
||||
|
||||
Future destroy() async {
|
||||
@@ -1,26 +1,23 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_gizmo.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_gizmo.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_material.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_swapchain.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_view.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'resource_loader.dart';
|
||||
|
||||
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
||||
|
||||
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
|
||||
FFIFilamentConfig(
|
||||
{required super.resourceLoader,
|
||||
{super.resourceLoader = null,
|
||||
super.backend = Backend.DEFAULT,
|
||||
super.platform = null,
|
||||
super.sharedContext = null,
|
||||
@@ -38,9 +35,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
final Pointer<TRenderTicker> renderTicker;
|
||||
final Pointer<TNameComponentManager> nameComponentManager;
|
||||
|
||||
final Future<Uint8List> Function(String uri) resourceLoader;
|
||||
late final Future<Uint8List> Function(String uri) resourceLoader;
|
||||
|
||||
late final _logger = Logger(this.runtimeType.toString());
|
||||
static final _logger = Logger("FFIFilamentApp");
|
||||
|
||||
FFIFilamentApp(
|
||||
this.engine,
|
||||
@@ -52,7 +49,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
this.ubershaderMaterialProvider,
|
||||
this.renderTicker,
|
||||
this.nameComponentManager,
|
||||
this.resourceLoader)
|
||||
Future<Uint8List> Function(String uri)? resourceLoader)
|
||||
: super(
|
||||
engine: engine,
|
||||
gltfAssetLoader: gltfAssetLoader,
|
||||
@@ -60,15 +57,13 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
transformManager: transformManager,
|
||||
lightManager: lightManager,
|
||||
renderableManager: renderableManager,
|
||||
ubershaderMaterialProvider: ubershaderMaterialProvider) {}
|
||||
|
||||
static Future<Uint8List> _defaultResourceLoader(String path) {
|
||||
print("Loading file $path");
|
||||
return File(path).readAsBytes();
|
||||
ubershaderMaterialProvider: ubershaderMaterialProvider) {
|
||||
this.resourceLoader = resourceLoader ?? defaultResourceLoader;
|
||||
}
|
||||
|
||||
static Future create({FFIFilamentConfig? config}) async {
|
||||
config ??= FFIFilamentConfig(resourceLoader: _defaultResourceLoader);
|
||||
config ??= FFIFilamentConfig();
|
||||
|
||||
if (FilamentApp.instance != null) {
|
||||
await FilamentApp.instance!.destroy();
|
||||
}
|
||||
@@ -78,7 +73,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
|
||||
final engine = await withPointerCallback<TEngine>((cb) =>
|
||||
Engine_createRenderThread(
|
||||
TBackend.values[config!.backend.index].index,
|
||||
config!.backend.value,
|
||||
config.platform ?? nullptr,
|
||||
config.sharedContext ?? nullptr,
|
||||
config.stereoscopicEyeCount,
|
||||
@@ -96,7 +91,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
final lightManager = Engine_getLightManager(engine);
|
||||
final renderableManager = Engine_getRenderableManager(engine);
|
||||
|
||||
final renderTicker = RenderTicker_create(renderer);
|
||||
final renderTicker = RenderTicker_create(engine, renderer);
|
||||
|
||||
RenderThread_setRenderTicker(renderTicker);
|
||||
|
||||
@@ -113,18 +108,25 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
renderTicker,
|
||||
nameComponentManager,
|
||||
config.resourceLoader);
|
||||
_logger.info("Initialization complete");
|
||||
}
|
||||
|
||||
final _swapChains = <FFISwapChain, List<FFIView>>{};
|
||||
final viewsPtr = calloc<Pointer<TView>>(255);
|
||||
late Pointer<PointerClass<TView>> viewsPtr =
|
||||
allocate<PointerClass>(255).cast();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future updateRenderOrder() async {
|
||||
_logger.info("updateRenderOrder");
|
||||
if (_swapChains.length == 0) {
|
||||
_logger.warning("No swapchains, ignoring updateRenderOrder");
|
||||
}
|
||||
for (final swapChain in _swapChains.keys) {
|
||||
final views = _swapChains[swapChain];
|
||||
if (views == null) {
|
||||
_logger.info("No views found for swapchain $swapChain");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -137,6 +139,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
}
|
||||
RenderTicker_setRenderable(
|
||||
renderTicker, swapChain.swapChain, viewsPtr, numRenderable);
|
||||
_logger.info("Updated render order, $numRenderable renderable views");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +230,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
RenderThread_destroy();
|
||||
RenderTicker_destroy(renderTicker);
|
||||
|
||||
calloc.free(viewsPtr);
|
||||
free(viewsPtr);
|
||||
FilamentApp.instance = null;
|
||||
for (final callback in _onDestroy) {
|
||||
await callback.call();
|
||||
@@ -242,6 +245,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
Future destroyAsset(covariant FFIAsset asset) async {
|
||||
await withVoidCallback(
|
||||
(cb) => SceneAsset_destroyRenderThread(asset.asset, cb));
|
||||
await asset.dispose();
|
||||
}
|
||||
|
||||
///
|
||||
@@ -298,8 +302,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
levels,
|
||||
bitmask,
|
||||
importedTextureHandle ?? 0,
|
||||
TTextureSamplerType.values[textureSamplerType.index],
|
||||
TTextureFormat.values[textureFormat.index],
|
||||
textureSamplerType.index,
|
||||
textureFormat.index,
|
||||
cb);
|
||||
});
|
||||
if (texturePtr == nullptr) {
|
||||
@@ -324,24 +328,17 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
TextureCompareMode compareMode = TextureCompareMode.NONE,
|
||||
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
|
||||
final samplerPtr = TextureSampler_create();
|
||||
TextureSampler_setMinFilter(
|
||||
samplerPtr, TSamplerMinFilter.values[minFilter.index]);
|
||||
TextureSampler_setMagFilter(
|
||||
samplerPtr, TSamplerMagFilter.values[magFilter.index]);
|
||||
TextureSampler_setWrapModeS(
|
||||
samplerPtr, TSamplerWrapMode.values[wrapS.index]);
|
||||
TextureSampler_setWrapModeT(
|
||||
samplerPtr, TSamplerWrapMode.values[wrapT.index]);
|
||||
TextureSampler_setWrapModeR(
|
||||
samplerPtr, TSamplerWrapMode.values[wrapR.index]);
|
||||
TextureSampler_setMinFilter(samplerPtr, minFilter.index);
|
||||
TextureSampler_setMagFilter(samplerPtr, magFilter.index);
|
||||
TextureSampler_setWrapModeS(samplerPtr, wrapS.index);
|
||||
TextureSampler_setWrapModeT(samplerPtr, wrapT.index);
|
||||
TextureSampler_setWrapModeR(samplerPtr, wrapR.index);
|
||||
if (anisotropy > 0) {
|
||||
TextureSampler_setAnisotropy(samplerPtr, anisotropy);
|
||||
}
|
||||
|
||||
TextureSampler_setCompareMode(
|
||||
samplerPtr,
|
||||
TSamplerCompareMode.values[compareMode.index],
|
||||
TSamplerCompareFunc.values[compareFunc.index]);
|
||||
samplerPtr, compareMode.index, compareFunc.index);
|
||||
|
||||
return FFITextureSampler(samplerPtr);
|
||||
}
|
||||
@@ -351,11 +348,20 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
///
|
||||
Future<LinearImage> decodeImage(Uint8List data) async {
|
||||
final name = "image";
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var ptr = Image_decode(
|
||||
data.address,
|
||||
data.length,
|
||||
name.toNativeUtf8().cast<Char>(),
|
||||
);
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
data.free();
|
||||
}
|
||||
if (ptr == nullptr) {
|
||||
throw Exception("Failed to decode image");
|
||||
}
|
||||
@@ -374,9 +380,17 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
///
|
||||
///
|
||||
Future<Material> createMaterial(Uint8List data) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var ptr = await withPointerCallback<TMaterial>((cb) {
|
||||
Engine_buildMaterialRenderThread(engine, data.address, data.length, cb);
|
||||
});
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
data.free();
|
||||
}
|
||||
return FFIMaterial(ptr, this);
|
||||
}
|
||||
|
||||
@@ -420,6 +434,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
bool hasSheen = false,
|
||||
bool hasIOR = false,
|
||||
bool hasVolume = false}) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
|
||||
final key = Struct.create<TMaterialKey>();
|
||||
|
||||
key.doubleSided = doubleSided;
|
||||
@@ -464,6 +483,10 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
MaterialProvider_createMaterialInstanceRenderThread(
|
||||
ubershaderMaterialProvider, key.address, cb);
|
||||
});
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
}
|
||||
if (materialInstance == nullptr) {
|
||||
throw Exception("Failed to create material instance");
|
||||
}
|
||||
@@ -506,7 +529,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
final swapchain = _swapChains.keys.first;
|
||||
final view = _swapChains[swapchain]!.first;
|
||||
await withBoolCallback((cb) {
|
||||
Renderer_beginFrameRenderThread(renderer, swapchain.swapChain, 0, cb);
|
||||
Renderer_beginFrameRenderThread(
|
||||
renderer, swapchain.swapChain, 0.toBigInt, cb);
|
||||
});
|
||||
await withVoidCallback((cb) {
|
||||
Renderer_renderRenderThread(
|
||||
@@ -515,10 +539,16 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
cb,
|
||||
);
|
||||
});
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Renderer_endFrameRenderThread(renderer, cb);
|
||||
});
|
||||
|
||||
if (FILAMENT_SINGLE_THREADED) {
|
||||
await withVoidCallback((cb) => Engine_executeRenderThread(engine, cb));
|
||||
} else {
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_flushAndWaitRenderThread(engine, cb));
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
@@ -581,19 +611,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
for (final hook in _hooks) {
|
||||
await hook.call();
|
||||
}
|
||||
final completer = Completer();
|
||||
|
||||
final callback = NativeCallable<Void Function()>.listener(() {
|
||||
completer.complete(true);
|
||||
});
|
||||
|
||||
RenderThread_requestFrame(callback.nativeFunction.cast());
|
||||
|
||||
try {
|
||||
await completer.future.timeout(Duration(seconds: 1));
|
||||
} catch (err) {
|
||||
print("WARNING - render call timed out");
|
||||
}
|
||||
RenderThread_requestFrameAsync();
|
||||
}
|
||||
|
||||
///
|
||||
@@ -669,7 +688,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
PixelDataFormat pixelDataFormat = PixelDataFormat.RGBA,
|
||||
PixelDataType pixelDataType = PixelDataType.FLOAT,
|
||||
Future Function(View)? beforeRender}) async {
|
||||
|
||||
if (swapChain == null) {
|
||||
if (_swapChains.isEmpty) {
|
||||
throw Exception("No swapchains registered");
|
||||
@@ -683,7 +701,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
await updateRenderOrder();
|
||||
|
||||
await withBoolCallback((cb) {
|
||||
Renderer_beginFrameRenderThread(renderer, swapChain!.swapChain, 0, cb);
|
||||
Renderer_beginFrameRenderThread(
|
||||
renderer, swapChain!.swapChain, 0.toBigInt, cb);
|
||||
});
|
||||
final views = <FFIView>[];
|
||||
if (view != null) {
|
||||
@@ -720,6 +739,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
: view.renderTarget!.renderTarget,
|
||||
// TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||
// TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||
// TPixelDataFormat.fromValue(pixelDataFormat.value),
|
||||
// TPixelDataType.fromValue(pixelDataType.value),
|
||||
pixelDataFormat.value,
|
||||
pixelDataType.value,
|
||||
pixelBuffer.address,
|
||||
@@ -734,7 +755,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
});
|
||||
|
||||
await withVoidCallback((cb) {
|
||||
Engine_flushAndWaitRenderThead(engine, cb);
|
||||
if (FILAMENT_SINGLE_THREADED) {
|
||||
Engine_executeRenderThread(engine, cb);
|
||||
} else {
|
||||
Engine_flushAndWaitRenderThread(engine, cb);
|
||||
}
|
||||
});
|
||||
return pixelBuffers;
|
||||
}
|
||||
@@ -759,70 +784,96 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
int layer = 0,
|
||||
String? relativeResourcePath,
|
||||
bool loadResourcesAsync = false}) async {
|
||||
if (relativeResourcePath != null && !relativeResourcePath.endsWith("/")) {
|
||||
relativeResourcePath = "$relativeResourcePath/";
|
||||
}
|
||||
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||
(cb) => GltfResourceLoader_createRenderThread(engine,
|
||||
relativeResourcePath?.toNativeUtf8().cast<Char>() ?? nullptr, cb));
|
||||
|
||||
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
||||
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader, data.address,
|
||||
data.length, numInstances, cb));
|
||||
|
||||
if (filamentAsset == nullptr) {
|
||||
throw Exception("An error occurred loading the asset");
|
||||
}
|
||||
|
||||
var resourceUris = FilamentAsset_getResourceUris(filamentAsset);
|
||||
var resourceUriCount = FilamentAsset_getResourceUriCount(filamentAsset);
|
||||
final resources = <FinalizableUint8List>[];
|
||||
try {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
|
||||
for (int i = 0; i < resourceUriCount; i++) {
|
||||
final resourceUriDart = resourceUris[i].cast<Utf8>().toDartString();
|
||||
final resourceData = await resourceLoader(relativeResourcePath == null
|
||||
? resourceUriDart
|
||||
: "$relativeResourcePath/$resourceUriDart");
|
||||
loadResourcesAsync = FILAMENT_SINGLE_THREADED;
|
||||
|
||||
resources.add(FinalizableUint8List(resourceUris[i], resourceData));
|
||||
|
||||
await withVoidCallback((cb) =>
|
||||
GltfResourceLoader_addResourceDataRenderThread(
|
||||
gltfResourceLoader,
|
||||
resourceUris[i],
|
||||
resourceData.address,
|
||||
resourceData.lengthInBytes,
|
||||
if (relativeResourcePath != null && !relativeResourcePath.endsWith("/")) {
|
||||
relativeResourcePath = "$relativeResourcePath/";
|
||||
}
|
||||
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||
(cb) => GltfResourceLoader_createRenderThread(
|
||||
engine,
|
||||
relativeResourcePath?.toNativeUtf8().cast<Char>() ?? nullptr,
|
||||
cb));
|
||||
}
|
||||
if (loadResourcesAsync) {
|
||||
final result = await withBoolCallback((cb) => GltfResourceLoader_asyncBeginLoadRenderThread(gltfResourceLoader, filamentAsset, cb));
|
||||
if(!result) {
|
||||
throw Exception("Failed to begin async loading");
|
||||
|
||||
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
||||
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader,
|
||||
data.address, data.length, numInstances, cb));
|
||||
|
||||
if (filamentAsset == nullptr) {
|
||||
throw Exception("An error occurred loading the asset");
|
||||
}
|
||||
|
||||
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
||||
var resourceUris = FilamentAsset_getResourceUris(filamentAsset);
|
||||
var resourceUriCount = FilamentAsset_getResourceUriCount(filamentAsset);
|
||||
|
||||
for (int i = 0; i < resourceUriCount; i++) {
|
||||
final resourceUriDart = resourceUris[i].cast<Utf8>().toDartString();
|
||||
final resourceData = await resourceLoader(relativeResourcePath == null
|
||||
? resourceUriDart
|
||||
: "$relativeResourcePath/$resourceUriDart");
|
||||
|
||||
resources.add(FinalizableUint8List(resourceUris[i], resourceData));
|
||||
|
||||
await withVoidCallback((cb) =>
|
||||
GltfResourceLoader_addResourceDataRenderThread(
|
||||
gltfResourceLoader,
|
||||
resourceUris[i],
|
||||
resourceData.address,
|
||||
resourceData.lengthInBytes,
|
||||
cb));
|
||||
}
|
||||
if (loadResourcesAsync) {
|
||||
final result = await withBoolCallback((cb) =>
|
||||
GltfResourceLoader_asyncBeginLoadRenderThread(
|
||||
gltfResourceLoader, filamentAsset, cb));
|
||||
if (!result) {
|
||||
throw Exception("Failed to begin async loading");
|
||||
}
|
||||
|
||||
var progress = await withFloatCallback((cb) => GltfResourceLoader_asyncGetLoadProgressRenderThread(gltfResourceLoader, cb));
|
||||
while(progress < 1.0) {
|
||||
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
||||
progress = await withFloatCallback((cb) => GltfResourceLoader_asyncGetLoadProgressRenderThread(gltfResourceLoader, cb));
|
||||
|
||||
var progress = await withFloatCallback((cb) =>
|
||||
GltfResourceLoader_asyncGetLoadProgressRenderThread(
|
||||
gltfResourceLoader, cb));
|
||||
while (progress < 1.0) {
|
||||
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
||||
progress = await withFloatCallback((cb) =>
|
||||
GltfResourceLoader_asyncGetLoadProgressRenderThread(
|
||||
gltfResourceLoader, cb));
|
||||
}
|
||||
} else {
|
||||
final result = await withBoolCallback((cb) =>
|
||||
GltfResourceLoader_loadResourcesRenderThread(
|
||||
gltfResourceLoader, filamentAsset, cb));
|
||||
if (!result) {
|
||||
throw Exception("Failed to load resources");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final result = await withBoolCallback((cb) =>
|
||||
GltfResourceLoader_loadResourcesRenderThread(
|
||||
gltfResourceLoader, filamentAsset, cb));
|
||||
if (!result) {
|
||||
throw Exception("Failed to load resources");
|
||||
|
||||
final asset = await withPointerCallback<TSceneAsset>((cb) =>
|
||||
SceneAsset_createFromFilamentAssetRenderThread(engine,
|
||||
gltfAssetLoader, nameComponentManager, filamentAsset, cb));
|
||||
|
||||
await withVoidCallback((cb) => GltfResourceLoader_destroyRenderThread(
|
||||
engine, gltfResourceLoader, cb));
|
||||
|
||||
return FFIAsset(asset, this, animationManager.cast<TAnimationManager>());
|
||||
} finally {
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
data.free();
|
||||
for (final resource in resources) {
|
||||
resource.data.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final asset = await withPointerCallback<TSceneAsset>((cb) =>
|
||||
SceneAsset_createFromFilamentAssetRenderThread(
|
||||
engine, gltfAssetLoader, nameComponentManager, filamentAsset, cb));
|
||||
|
||||
await withVoidCallback((cb) =>
|
||||
GltfResourceLoader_destroyRenderThread(engine, gltfResourceLoader, cb));
|
||||
return FFIAsset(asset, this, animationManager.cast<TAnimationManager>());
|
||||
}
|
||||
|
||||
Future destroyView(covariant FFIView view) async {
|
||||
@@ -833,12 +884,13 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
}
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_destroyViewRenderThread(engine, view.view, cb));
|
||||
for(final swapchain in _swapChains.keys) {
|
||||
if(_swapChains[swapchain]!.contains(view)) {
|
||||
for (final swapchain in _swapChains.keys) {
|
||||
if (_swapChains[swapchain]!.contains(view)) {
|
||||
_swapChains[swapchain]!.remove(view);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
await view.dispose();
|
||||
}
|
||||
|
||||
Future destroyScene(covariant FFIScene scene) async {
|
||||
@@ -847,9 +899,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
}
|
||||
|
||||
Future<Pointer<TColorGrading>> createColorGrading(ToneMapper mapper) async {
|
||||
return withPointerCallback<TColorGrading>((cb) =>
|
||||
ColorGrading_createRenderThread(
|
||||
engine, TToneMapping.values[mapper.index], cb));
|
||||
return withPointerCallback<TColorGrading>(
|
||||
(cb) => ColorGrading_createRenderThread(engine, mapper.index, cb));
|
||||
}
|
||||
|
||||
FFIMaterial? _gizmoMaterial;
|
||||
@@ -859,6 +910,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
///
|
||||
Future<GizmoAsset> createGizmo(covariant FFIView view,
|
||||
Pointer animationManager, GizmoType gizmoType) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
|
||||
if (_gizmoMaterial == null) {
|
||||
final materialPtr = await withPointerCallback<TMaterial>((cb) {
|
||||
Material_createGizmoMaterialRenderThread(engine, cb);
|
||||
@@ -867,7 +923,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
}
|
||||
|
||||
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||
(cb) => GltfResourceLoader_createRenderThread(engine, nullptr, cb));
|
||||
(cb) =>
|
||||
GltfResourceLoader_createRenderThread(engine, nullptr.cast(), cb));
|
||||
|
||||
final gizmo = await withPointerCallback<TGizmo>((cb) {
|
||||
Gizmo_createRenderThread(
|
||||
@@ -877,7 +934,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
nameComponentManager,
|
||||
view.view,
|
||||
_gizmoMaterial!.pointer,
|
||||
TGizmoType.values[gizmoType.index],
|
||||
gizmoType.index,
|
||||
cb);
|
||||
});
|
||||
if (gizmo == nullptr) {
|
||||
@@ -889,11 +946,17 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
SceneAsset_getChildEntities(
|
||||
gizmo.cast<TSceneAsset>(), gizmoEntities.address);
|
||||
|
||||
return FFIGizmo(gizmo.cast<TSceneAsset>(), this,
|
||||
final gizmoAsset = FFIGizmo(gizmo.cast<TSceneAsset>(), this,
|
||||
animationManager.cast<TAnimationManager>(),
|
||||
view: view,
|
||||
entities: gizmoEntities.toSet()
|
||||
..add(SceneAsset_getEntity(gizmo.cast<TSceneAsset>())));
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
gizmoEntities.free();
|
||||
}
|
||||
|
||||
return gizmoAsset;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -905,19 +968,24 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
{List<MaterialInstance>? materialInstances,
|
||||
bool keepData = false,
|
||||
bool addToScene = true}) async {
|
||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) {
|
||||
var ptrList = Int64List(materialInstances?.length ?? 0);
|
||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
||||
ptrList.setRange(
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<FFIMaterialInstance>()
|
||||
.map((mi) => mi.pointer.address)
|
||||
.toList());
|
||||
}
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
|
||||
return SceneAsset_createGeometryRenderThread(
|
||||
final ptrList = IntPtrList(materialInstances?.length ?? 0);
|
||||
if (materialInstances != null) {
|
||||
ptrList.setRange(
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<FFIMaterialInstance>()
|
||||
.map((mi) => mi.pointer.address)
|
||||
.toList());
|
||||
}
|
||||
|
||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) {
|
||||
var ptr = SceneAsset_createGeometryRenderThread(
|
||||
engine,
|
||||
geometry.vertices.address,
|
||||
geometry.vertices.length,
|
||||
@@ -928,10 +996,20 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
geometry.indices.address,
|
||||
geometry.indices.length,
|
||||
geometry.primitiveType.index,
|
||||
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
||||
ptrList.length,
|
||||
ptrList.address.cast(),
|
||||
ptrList.length ?? 0,
|
||||
callback);
|
||||
return ptr;
|
||||
});
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
ptrList?.free();
|
||||
geometry.vertices.free();
|
||||
geometry.normals?.free();
|
||||
geometry.uvs?.free();
|
||||
}
|
||||
|
||||
if (assetPtr == nullptr) {
|
||||
throw Exception("Failed to create geometry");
|
||||
}
|
||||
@@ -943,7 +1021,12 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
///
|
||||
///
|
||||
Future flush() async {
|
||||
await withVoidCallback((cb) => Engine_flushAndWaitRenderThead(engine, cb));
|
||||
if (FILAMENT_SINGLE_THREADED) {
|
||||
await withVoidCallback((cb) => Engine_executeRenderThread(engine, cb));
|
||||
} else {
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_flushAndWaitRenderThread(engine, cb));
|
||||
}
|
||||
}
|
||||
|
||||
final _onDestroy = <Future Function()>[];
|
||||
@@ -955,10 +1038,3 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
_onDestroy.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
class FinalizableUint8List implements Finalizable {
|
||||
final Pointer name;
|
||||
final Uint8List data;
|
||||
|
||||
FinalizableUint8List(this.name, this.data);
|
||||
}
|
||||
@@ -1,29 +1,19 @@
|
||||
import 'dart:async';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
import 'ffi_view.dart';
|
||||
|
||||
class FFIGizmo extends FFIAsset implements GizmoAsset {
|
||||
final Set<ThermionEntity> entities;
|
||||
late NativeCallable<GizmoPickCallbackFunction> _nativeCallback;
|
||||
|
||||
late final CallbackHolder<GizmoPickCallbackFunction> _callbackHolder;
|
||||
|
||||
void Function(GizmoPickResultType axis, Vector3 coords)? _callback;
|
||||
|
||||
late FFIView view;
|
||||
|
||||
void _onPickResult(int resultType, double x, double y, double z) {
|
||||
_callback?.call(GizmoPickResultType.values[resultType], Vector3(x, y, z));
|
||||
}
|
||||
|
||||
bool isNonPickable(ThermionEntity entity) {
|
||||
throw UnimplementedError();
|
||||
// return SceneManager_isGridEntity(sceneManager, entity);
|
||||
}
|
||||
|
||||
bool isGizmoEntity(ThermionEntity entity) => entities.contains(entity);
|
||||
|
||||
FFIGizmo(
|
||||
super.asset,
|
||||
super.app,
|
||||
@@ -32,10 +22,38 @@ class FFIGizmo extends FFIAsset implements GizmoAsset {
|
||||
required this.view,
|
||||
required this.entities,
|
||||
}) {
|
||||
_nativeCallback =
|
||||
NativeCallable<GizmoPickCallbackFunction>.listener(_onPickResult);
|
||||
|
||||
_callbackHolder = _onPickResult.asCallback();
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future dispose() async {
|
||||
_callbackHolder.dispose();
|
||||
}
|
||||
|
||||
|
||||
void _onPickResult(int resultType, double x, double y, double z) {
|
||||
|
||||
final type = switch(resultType) {
|
||||
TGizmoPickResultType.AxisX => GizmoPickResultType.AxisX,
|
||||
TGizmoPickResultType.AxisY => GizmoPickResultType.AxisY,
|
||||
TGizmoPickResultType.AxisZ => GizmoPickResultType.AxisZ,
|
||||
TGizmoPickResultType.None => GizmoPickResultType.None,
|
||||
TGizmoPickResultType.Parent => GizmoPickResultType.Parent,
|
||||
_ => throw UnsupportedError(resultType.toString())
|
||||
};
|
||||
_callback?.call(type, Vector3(x, y, z));
|
||||
}
|
||||
|
||||
bool isNonPickable(ThermionEntity entity) {
|
||||
throw UnimplementedError();
|
||||
// return SceneManager_isGridEntity(sceneManager, entity);
|
||||
}
|
||||
|
||||
bool isGizmoEntity(ThermionEntity entity) => entities.contains(entity);
|
||||
|
||||
@override
|
||||
Future removeStencilHighlight() async {
|
||||
throw Exception("Not supported for gizmo");
|
||||
@@ -58,13 +76,18 @@ class FFIGizmo extends FFIAsset implements GizmoAsset {
|
||||
final viewport = await view.getViewport();
|
||||
y = viewport.height - y;
|
||||
|
||||
Gizmo_pick(asset.cast<TGizmo>(), x, y, _nativeCallback.nativeFunction);
|
||||
Gizmo_pick(asset.cast<TGizmo>(), x, y, _callbackHolder.pointer);
|
||||
}
|
||||
|
||||
@override
|
||||
Future highlight(Axis axis) async {
|
||||
Gizmo_unhighlight(asset.cast<TGizmo>());
|
||||
Gizmo_highlight(asset.cast<TGizmo>(), TGizmoAxis.values[axis.index]);
|
||||
final tAxis = switch(axis) {
|
||||
Axis.X => TGizmoAxis.X,
|
||||
Axis.Y => TGizmoAxis.Y,
|
||||
Axis.Z => TGizmoAxis.Z
|
||||
};
|
||||
Gizmo_highlight(asset.cast<TGizmo>(), tAxis);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1,9 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class FFIMaterial extends Material {
|
||||
@@ -73,7 +70,11 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
|
||||
@override
|
||||
Future setParameterFloat3Array(String name, List<Vector3> array) async {
|
||||
final ptr = name.toNativeUtf8(allocator: calloc).cast<Char>();
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
final ptr = name.toNativeUtf8().cast<Char>();
|
||||
final data = Float64List(array.length * 3);
|
||||
int i = 0;
|
||||
for (final item in array) {
|
||||
@@ -84,7 +85,11 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
}
|
||||
MaterialInstance_setParameterFloat3Array(
|
||||
pointer, ptr, data.address, array.length * 3);
|
||||
calloc.free(ptr);
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
data.free();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -102,45 +107,38 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
|
||||
@override
|
||||
Future setDepthFunc(SamplerCompareFunction depthFunc) async {
|
||||
MaterialInstance_setDepthFunc(
|
||||
pointer, TSamplerCompareFunc.values[depthFunc.index]);
|
||||
MaterialInstance_setDepthFunc(pointer, depthFunc.index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilCompareFunction(SamplerCompareFunction func,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilCompareFunction(
|
||||
pointer,
|
||||
TSamplerCompareFunc.values[func.index],
|
||||
TStencilFace.values[face.index]);
|
||||
MaterialInstance_setStencilCompareFunction(pointer, func.index, face.index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpDepthFail(StencilOperation op,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilOpDepthFail(pointer,
|
||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
||||
MaterialInstance_setStencilOpDepthFail(pointer, op.index, face.index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpDepthStencilPass(StencilOperation op,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilOpDepthStencilPass(pointer,
|
||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
||||
MaterialInstance_setStencilOpDepthStencilPass(
|
||||
pointer, op.index, face.index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpStencilFail(StencilOperation op,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilOpStencilFail(pointer,
|
||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
||||
MaterialInstance_setStencilOpStencilFail(pointer, op.index, face.index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilReferenceValue(int value,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilReferenceValue(
|
||||
pointer, value, TStencilFace.values[face.index]);
|
||||
MaterialInstance_setStencilReferenceValue(pointer, value, face.index);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -150,8 +148,8 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
|
||||
@override
|
||||
Future setCullingMode(CullingMode cullingMode) async {
|
||||
MaterialInstance_setCullingMode(
|
||||
pointer, TCullingMode.values[cullingMode.index]);
|
||||
MaterialInstance_setCullingMode(pointer, cullingMode.index);
|
||||
;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -177,8 +175,7 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
|
||||
@override
|
||||
Future setTransparencyMode(TransparencyMode mode) async {
|
||||
MaterialInstance_setTransparencyMode(
|
||||
pointer, TTransparencyMode.values[mode.index]);
|
||||
MaterialInstance_setTransparencyMode(pointer, mode.index);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -196,13 +193,7 @@ class FFIMaterialInstance extends MaterialInstance {
|
||||
|
||||
@override
|
||||
Future setParameterMat4(String name, Matrix4 matrix) async {
|
||||
final completer = Completer();
|
||||
final func = () {
|
||||
MaterialInstance_setParameterMat4(pointer, name.toNativeUtf8().cast<Char>(), matrix.storage.address);
|
||||
completer.complete();
|
||||
};
|
||||
final nativeCallable = NativeCallable<Void Function()>.listener(func);
|
||||
RenderThread_addTask(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
MaterialInstance_setParameterMat4(
|
||||
pointer, name.toNativeUtf8().cast<Char>(), matrix.storage.address);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class FFIRenderTarget extends RenderTarget {
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
||||
import 'callbacks.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
|
||||
class FFIScene extends Scene {
|
||||
final Pointer<TScene> scene;
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class FFISwapChain extends SwapChain {
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class FFITexture extends Texture {
|
||||
@@ -11,13 +11,15 @@ class FFITexture extends Texture {
|
||||
|
||||
Future<void> setLinearImage(covariant FFILinearImage image,
|
||||
PixelDataFormat format, PixelDataType type) async {
|
||||
final tPixelDataFormat = format.value;
|
||||
final tPixelDataType = type.value;
|
||||
final result = await withBoolCallback((cb) {
|
||||
Texture_loadImageRenderThread(
|
||||
_engine,
|
||||
pointer,
|
||||
image.pointer,
|
||||
format.index,
|
||||
type.index,
|
||||
tPixelDataFormat,
|
||||
tPixelDataType,
|
||||
cb);
|
||||
});
|
||||
|
||||
@@ -114,28 +116,29 @@ class FFITexture extends Texture {
|
||||
Uint8List buffer,
|
||||
PixelDataFormat format,
|
||||
PixelDataType type) async {
|
||||
final success = await withBoolCallback((cb) {
|
||||
Texture_setImageWithDepthRenderThread(
|
||||
_engine,
|
||||
pointer,
|
||||
level,
|
||||
buffer.address,
|
||||
buffer.lengthInBytes,
|
||||
0,
|
||||
0,
|
||||
zOffset,
|
||||
width,
|
||||
height,
|
||||
channels,
|
||||
depth,
|
||||
format.index,
|
||||
type.index,
|
||||
cb);
|
||||
});
|
||||
throw UnimplementedError();
|
||||
// final success = await withBoolCallback((cb) {
|
||||
// Texture_setImageWithDepthRenderThread(
|
||||
// _engine,
|
||||
// pointer,
|
||||
// level,
|
||||
// buffer.address,
|
||||
// buffer.lengthInBytes,
|
||||
// 0,
|
||||
// 0,
|
||||
// zOffset,
|
||||
// width,
|
||||
// height,
|
||||
// channels,
|
||||
// depth,
|
||||
// format.index,
|
||||
// type.index,
|
||||
// cb);
|
||||
// });
|
||||
|
||||
if (!success) {
|
||||
throw Exception("Failed to set image");
|
||||
}
|
||||
// if (!success) {
|
||||
// throw Exception("Failed to set image");
|
||||
// }
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -171,16 +174,12 @@ class FFILinearImage extends LinearImage {
|
||||
[String name = "image"]) async {
|
||||
final namePtr = name.toNativeUtf8();
|
||||
|
||||
try {
|
||||
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
|
||||
Image_decodeRenderThread(
|
||||
data.address, data.lengthInBytes, namePtr.cast(), cb);
|
||||
});
|
||||
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
|
||||
Image_decodeRenderThread(
|
||||
data.address, data.lengthInBytes, namePtr.cast(), cb);
|
||||
});
|
||||
|
||||
return FFILinearImage(imagePtr);
|
||||
} finally {
|
||||
calloc.free(namePtr);
|
||||
}
|
||||
return FFILinearImage(imagePtr);
|
||||
}
|
||||
|
||||
Future<void> destroy() async {
|
||||
@@ -2,12 +2,12 @@ import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'callbacks.dart';
|
||||
|
||||
import 'ffi_camera.dart';
|
||||
|
||||
class FFIView extends View {
|
||||
@@ -24,14 +24,24 @@ class FFIView extends View {
|
||||
|
||||
FFIRenderTarget? renderTarget;
|
||||
|
||||
late CallbackHolder<PickCallbackFunction> _onPickResultHolder;
|
||||
|
||||
|
||||
FFIView(this.view, this.app) {
|
||||
final renderTargetPtr = View_getRenderTarget(view);
|
||||
if (renderTargetPtr != nullptr) {
|
||||
renderTarget = FFIRenderTarget(renderTargetPtr, app);
|
||||
}
|
||||
|
||||
_onPickResultCallable =
|
||||
NativeCallable<PickCallbackFunction>.listener(_onPickResult);
|
||||
_onPickResultHolder =
|
||||
_onPickResult.asCallback();
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future dispose() async {
|
||||
_onPickResultHolder.dispose();
|
||||
}
|
||||
|
||||
///
|
||||
@@ -76,7 +86,7 @@ class FFIView extends View {
|
||||
|
||||
@override
|
||||
Future<Viewport> getViewport() async {
|
||||
TViewport vp = View_getViewport(view);
|
||||
final vp = View_getViewport(view);
|
||||
return Viewport(vp.left, vp.bottom, vp.width, vp.height);
|
||||
}
|
||||
|
||||
@@ -141,7 +151,7 @@ class FFIView extends View {
|
||||
|
||||
@override
|
||||
Future setRenderQuality(QualityLevel quality) async {
|
||||
View_setRenderQuality(view, TQualityLevel.values[quality.index]);
|
||||
View_setRenderQuality(view, quality.index);
|
||||
}
|
||||
|
||||
Future setScene(covariant FFIScene scene) async {
|
||||
@@ -154,7 +164,7 @@ class FFIView extends View {
|
||||
}
|
||||
|
||||
Future setBlendMode(BlendMode blendMode) async {
|
||||
View_setBlendMode(view, TBlendMode.values[blendMode.index]);
|
||||
View_setBlendMode(view, blendMode.index);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -168,7 +178,6 @@ class FFIView extends View {
|
||||
static int kMaxPickRequests = 1024;
|
||||
final _pickRequests = List<({void Function(PickResult) handler, int x, int y})?>.generate(kMaxPickRequests, (idx) => null);
|
||||
|
||||
late NativeCallable<PickCallbackFunction> _onPickResultCallable;
|
||||
|
||||
///
|
||||
///
|
||||
@@ -184,7 +193,7 @@ class FFIView extends View {
|
||||
y = viewport.height - y;
|
||||
|
||||
View_pick(
|
||||
view, pickRequestId, x, y, _onPickResultCallable.nativeFunction);
|
||||
view, pickRequestId, x, y, _onPickResultHolder.pointer);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
|
||||
class GridOverlay extends FFIAsset {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export 'resource_loader_io.dart'
|
||||
if (dart.library.io) 'resource_loader_io.dart'
|
||||
if (dart.library.js_interop) 'resource_loader_js.dart';
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
Future<Uint8List> defaultResourceLoader(String path) {
|
||||
print("Loading file $path");
|
||||
return File(path).readAsBytes();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
Future<Uint8List> defaultResourceLoader(String path) async {
|
||||
if(path.startsWith("file://")) {
|
||||
throw Exception("Unsupported URI : $path");
|
||||
}
|
||||
|
||||
final response = await http.get(Uri.parse(path));
|
||||
return response.bodyBytes;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
library;
|
||||
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/layers.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
export 'geometry.dart';
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/layers.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
enum Projection { Perspective, Orthographic }
|
||||
@@ -1,15 +1,11 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:thermion_dart/src/filament/src/engine.dart';
|
||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class FilamentConfig<T, U> {
|
||||
final Backend backend;
|
||||
final T? renderCallback;
|
||||
final U? renderCallbackOwner;
|
||||
final Future<Uint8List> Function(String) resourceLoader;
|
||||
Future<Uint8List> Function(String)? resourceLoader;
|
||||
final U? platform;
|
||||
final U? sharedContext;
|
||||
final String? uberArchivePath;
|
||||
37
thermion_dart/lib/src/filament/src/interface/geometry.dart
Normal file
37
thermion_dart/lib/src/filament/src/interface/geometry.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
|
||||
import '../../../viewer/viewer.dart';
|
||||
|
||||
class Geometry {
|
||||
final Float32List vertices;
|
||||
final Uint16List indices;
|
||||
late final Float32List normals;
|
||||
late final Float32List uvs;
|
||||
final PrimitiveType primitiveType;
|
||||
|
||||
Geometry(
|
||||
this.vertices,
|
||||
this.indices, {
|
||||
Float32List? normals,
|
||||
Float32List? uvs,
|
||||
this.primitiveType = PrimitiveType.TRIANGLES,
|
||||
}) {
|
||||
this.uvs = uvs ?? Float32List(0);
|
||||
this.normals = normals ?? Float32List(0);
|
||||
if (this.uvs.length != 0 && this.uvs.length != (vertices.length ~/ 3 * 2)) {
|
||||
throw Exception(
|
||||
"Expected either ${indices.length * 2} UVs, got ${this.uvs!.length}");
|
||||
}
|
||||
}
|
||||
|
||||
void scale(double factor) {
|
||||
for (int i = 0; i < vertices.length; i++) {
|
||||
vertices[i] = vertices[i] * factor;
|
||||
}
|
||||
}
|
||||
|
||||
bool get hasNormals => normals?.isNotEmpty == true;
|
||||
bool get hasUVs => uvs?.isNotEmpty == true;
|
||||
}
|
||||
@@ -25,4 +25,7 @@ abstract class GizmoAsset extends ThermionAsset {
|
||||
Future unhighlight();
|
||||
bool isNonPickable(ThermionEntity entity);
|
||||
bool isGizmoEntity(ThermionEntity entity);
|
||||
|
||||
Future dispose();
|
||||
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '../../viewer/viewer.dart';
|
||||
import '../../../viewer/viewer.dart';
|
||||
|
||||
/// The result of a picking operation (see [ThermionViewer.pick] for more details).
|
||||
/// [x] and [y] refer to the original screen coordinates used to call [pick]; this should
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
enum BlendMode {
|
||||
@@ -57,7 +57,10 @@ abstract class View {
|
||||
Future pick(int x, int y, void Function(PickResult) resultHandler);
|
||||
|
||||
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future dispose();
|
||||
|
||||
|
||||
}
|
||||
@@ -78,12 +78,8 @@ class FixedOrbitRotateInputHandlerDelegate implements InputHandlerDelegate {
|
||||
|
||||
final camera = await view.getCamera();
|
||||
|
||||
final viewport = await view.getViewport();
|
||||
|
||||
var viewMatrix = await camera.getViewMatrix();
|
||||
var modelMatrix = await camera.getModelMatrix();
|
||||
var projectionMatrix = await camera.getProjectionMatrix();
|
||||
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
||||
|
||||
Vector3 currentPosition = modelMatrix.getTranslation();
|
||||
|
||||
Vector3 forward = modelMatrix.forward;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
import '../../viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
|
||||
class DartResourceLoader {
|
||||
static final _assets = <int, Pointer>{};
|
||||
static void loadResource(Pointer<Char> uri, Pointer<ResourceBuffer> out) {
|
||||
try {
|
||||
var data = File(uri.cast<Utf8>().toDartString().replaceAll("file://", ""))
|
||||
.readAsBytesSync();
|
||||
var ptr = calloc<Uint8>(data.lengthInBytes);
|
||||
ptr.asTypedList(data.lengthInBytes).setRange(0, data.lengthInBytes, data);
|
||||
|
||||
out.ref.data = ptr.cast<Void>();
|
||||
out.ref.size = data.lengthInBytes;
|
||||
out.ref.id = _assets.length;
|
||||
_assets[out.ref.id] = ptr;
|
||||
} catch (err) {
|
||||
print(err);
|
||||
out.ref.size = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void freeResource(ResourceBuffer rb) {
|
||||
calloc.free(_assets[rb.id]!);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:math' ;
|
||||
|
||||
import '../../../thermion_dart.dart';
|
||||
|
||||
class GeometryHelper {
|
||||
static Geometry fullscreenQuad() {
|
||||
final vertices =
|
||||
Float32List.fromList([-1.0, -1.0, 1.0, 3.0, -1.0, 1.0, -1.0, 3.0, 1.0]);
|
||||
final indices = [0, 1, 2];
|
||||
final vertices = Float32List.fromList([-1.0, -1.0, 1.0, 3.0, -1.0, 1.0, -1.0, 3.0, 1.0]);
|
||||
final indices = Uint16List.fromList([0, 1, 2]);
|
||||
return Geometry(vertices, indices);
|
||||
}
|
||||
|
||||
@@ -56,7 +54,7 @@ class GeometryHelper {
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
return Geometry(vertices, Uint16List.fromList(indices), normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry cube(
|
||||
@@ -236,7 +234,7 @@ class GeometryHelper {
|
||||
20, 21, 22, 20, 22, 23 // 4,0,3,4,3,7
|
||||
];
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
return Geometry(vertices, Uint16List.fromList(indices), normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
// Helper function to flip the Y coordinate of UV coordinates (y = 1.0 - y)
|
||||
@@ -316,7 +314,7 @@ class GeometryHelper {
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
return Geometry(vertices, Uint16List.fromList(indices), normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry conic(
|
||||
@@ -440,7 +438,7 @@ class GeometryHelper {
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
return Geometry(vertices, Uint16List.fromList(indices), normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
static Geometry plane(
|
||||
@@ -493,14 +491,14 @@ class GeometryHelper {
|
||||
])
|
||||
: null;
|
||||
|
||||
List<int> indices = [
|
||||
final indices = Uint16List.fromList([
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
];
|
||||
]);
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
@@ -640,7 +638,7 @@ class GeometryHelper {
|
||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||
|
||||
return Geometry(vertices, indices,
|
||||
return Geometry(vertices, Uint16List.fromList(indices),
|
||||
normals: _normals, uvs: _uvs, primitiveType: PrimitiveType.LINES);
|
||||
}
|
||||
|
||||
@@ -794,7 +792,7 @@ class GeometryHelper {
|
||||
])
|
||||
: null;
|
||||
|
||||
final indices = [
|
||||
final indices = Uint16List.fromList([
|
||||
// Front face
|
||||
0, 1, 2, 0, 2, 3,
|
||||
// Back face
|
||||
@@ -807,7 +805,7 @@ class GeometryHelper {
|
||||
16, 17, 18, 16, 18, 19,
|
||||
// Left face
|
||||
20, 21, 22, 20, 22, 23
|
||||
];
|
||||
]);
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
@@ -865,7 +863,7 @@ class GeometryHelper {
|
||||
: null;
|
||||
|
||||
// Define indices for triangular faces
|
||||
List<int> indices = [
|
||||
Uint16List indices = Uint16List.fromList([
|
||||
// Bottom face (rectangle)
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
@@ -883,7 +881,7 @@ class GeometryHelper {
|
||||
// Back rectangular face
|
||||
2, 3, 4,
|
||||
2, 4, 5,
|
||||
];
|
||||
]);
|
||||
|
||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:image/image.dart' as img;
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
Future<Uint8List> pixelBufferToBmp(Uint8List pixelBuffer, int width, int height,
|
||||
{bool hasAlpha = true, bool isFloat = false}) async {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Helper function to convert double4x4 to Matrix4
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:ffi';
|
||||
|
||||
Matrix4 double4x4ToMatrix4(double4x4 mat) {
|
||||
|
||||
return Matrix4.fromList([
|
||||
mat.col1[0],
|
||||
mat.col1[1],
|
||||
@@ -26,12 +25,16 @@ Matrix4 double4x4ToMatrix4(double4x4 mat) {
|
||||
|
||||
double4x4 matrix4ToDouble4x4(Matrix4 mat) {
|
||||
final out = Struct.create<double4x4>();
|
||||
Array<Float64> col1 =out.col1;
|
||||
Array<Float64> col2 = out.col2;
|
||||
Array<Float64> col3 =out.col3;
|
||||
Array<Float64> col4= out.col4;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
out.col1[i] = mat.storage[i];
|
||||
out.col2[i] = mat.storage[i + 4];
|
||||
out.col3[i] = mat.storage[i + 8];
|
||||
out.col4[i] = mat.storage[i + 12];
|
||||
col1[i] = mat.storage[i];
|
||||
col2[i] = mat.storage[i + 4];
|
||||
col3[i] = mat.storage[i + 8];
|
||||
col4[i] = mat.storage[i + 12];
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_view.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class TextureProjection {
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:thermion_dart/src/filament/src/light_options.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/background_image.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/grid_overlay.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/background_image.dart';
|
||||
import '../../../../filament/src/implementation/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||
import '../../../../filament/src/implementation/ffi_scene.dart';
|
||||
import '../../../../filament/src/implementation/grid_overlay.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import 'callbacks.dart';
|
||||
import 'ffi_camera.dart';
|
||||
import 'ffi_view.dart';
|
||||
import '../../../../filament/src/implementation/ffi_camera.dart';
|
||||
import '../../../../filament/src/implementation/ffi_view.dart';
|
||||
|
||||
const FILAMENT_ASSET_ERROR = 0;
|
||||
|
||||
@@ -50,6 +45,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
Future setViewport(int width, int height) async {
|
||||
print("Setting viewport to ${width}x${height}");
|
||||
await view.setViewport(width.toInt(), height.toInt());
|
||||
|
||||
for (final camera in _cameras) {
|
||||
@@ -121,8 +117,15 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future render() async {
|
||||
await withVoidCallback(
|
||||
(cb) => RenderTicker_renderRenderThread(app.renderTicker, 0, cb));
|
||||
await withVoidCallback((cb) =>
|
||||
RenderTicker_renderRenderThread(app.renderTicker, 0.toBigInt, cb));
|
||||
if (FILAMENT_SINGLE_THREADED) {
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_executeRenderThread(app.engine, cb));
|
||||
} else {
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_flushAndWaitRenderThread(app.engine, cb));
|
||||
}
|
||||
}
|
||||
|
||||
double _msPerFrame = 1000.0 / 60.0;
|
||||
@@ -248,11 +251,21 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
var data = await loadAssetFromUri(lightingPath);
|
||||
|
||||
indirectLight = await withPointerCallback<TIndirectLight>((cb) {
|
||||
Engine_buildIndirectLightRenderThread(
|
||||
app.engine, data.address, data.length, intensity, cb, nullptr);
|
||||
});
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
data.free();
|
||||
}
|
||||
data.free();
|
||||
Scene_setIndirectLight(scene.scene, indirectLight!);
|
||||
}
|
||||
|
||||
@@ -264,7 +277,18 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
if (indirectLight == null) {
|
||||
throw Exception("No IBL loaded");
|
||||
}
|
||||
|
||||
late Pointer stackPtr;
|
||||
if (FILAMENT_WASM) {
|
||||
//stackPtr = stackSave();
|
||||
}
|
||||
|
||||
IndirectLight_setRotation(indirectLight!, rotationMatrix.storage.address);
|
||||
|
||||
if (FILAMENT_WASM) {
|
||||
//stackRestore(stackPtr);
|
||||
rotationMatrix.storage.free();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
@@ -303,8 +327,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
|
||||
var entity = LightManager_createLight(app.engine, app.lightManager,
|
||||
TLightType.values[directLight.type.index]);
|
||||
var entity = LightManager_createLight(
|
||||
app.engine, app.lightManager, directLight.type.index);
|
||||
if (entity == FILAMENT_ASSET_ERROR) {
|
||||
throw Exception("Failed to add light to scene");
|
||||
}
|
||||
@@ -446,8 +470,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
@override
|
||||
Future setPostProcessing(bool enabled) async {
|
||||
View_setPostProcessing(view.view, enabled);
|
||||
await withVoidCallback(
|
||||
(cb) => Engine_flushAndWaitRenderThead(app.engine, cb));
|
||||
}
|
||||
|
||||
///
|
||||
@@ -478,10 +500,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
@override
|
||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa) async {
|
||||
if (Platform.isWindows && msaa) {
|
||||
if (!FILAMENT_SINGLE_THREADED && IS_WINDOWS && msaa) {
|
||||
throw Exception("MSAA is not currently supported on Windows");
|
||||
}
|
||||
|
||||
View_setAntiAliasing(view.view, msaa, fxaa, taa);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/light_options.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/layers.dart';
|
||||
import 'package:thermion_dart/src/filament/src/interface/light_options.dart';
|
||||
|
||||
import '../../filament/src/shared_types.dart';
|
||||
import '../../filament/src/interface/shared_types.dart';
|
||||
import 'dart:typed_data';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:async';
|
||||
|
||||
@@ -1,317 +0,0 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:thermion_dart/src/filament/src/light_options.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class ThermionViewerStub extends ThermionViewer {
|
||||
@override
|
||||
Future<ThermionEntity> addDirectLight(DirectLight light) {
|
||||
// TODO: implement addDirectLight
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future addToScene(covariant ThermionAsset asset) {
|
||||
// TODO: implement addToScene
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future clearBackgroundImage({bool destroy = false}) {
|
||||
// TODO: implement clearBackgroundImage
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Camera> createCamera() {
|
||||
// TODO: implement createCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionAsset> createGeometry(Geometry geometry,
|
||||
{List<MaterialInstance>? materialInstances,
|
||||
bool keepData = false,
|
||||
bool addToScene = true}) {
|
||||
// TODO: implement createGeometry
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future destroyAsset(ThermionAsset asset) {
|
||||
// TODO: implement destroyAsset
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future destroyAssets() {
|
||||
// TODO: implement destroyAssets
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future destroyCamera(covariant Camera camera) {
|
||||
// TODO: implement destroyCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future destroyLights() {
|
||||
// TODO: implement destroyLights
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future dispose() {
|
||||
// TODO: implement dispose
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Camera> getActiveCamera() {
|
||||
// TODO: implement getActiveCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
int getCameraCount() {
|
||||
// TODO: implement getCameraCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GizmoAsset> getGizmo(GizmoType type) {
|
||||
// TODO: implement getGizmo
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Aabb3> getRenderableBoundingBox(ThermionEntity entity) {
|
||||
// TODO: implement getRenderableBoundingBox
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Aabb2> getViewportBoundingBox(ThermionEntity entity) {
|
||||
// TODO: implement getViewportBoundingBox
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement initialized
|
||||
Future<bool> get initialized => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<ThermionAsset> loadGltf(String path,
|
||||
{bool addToScene = true,
|
||||
int numInstances = 1,
|
||||
bool keepData = false,
|
||||
String? relativeResourcePath}) {
|
||||
// TODO: implement loadGltf
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future loadIbl(String lightingPath, {double intensity = 30000}) {
|
||||
// TODO: implement loadIbl
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future loadSkybox(String skyboxPath) {
|
||||
// TODO: implement loadSkybox
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement msPerFrame
|
||||
double get msPerFrame => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
void onDispose(Future Function() callback) {
|
||||
// TODO: implement onDispose
|
||||
}
|
||||
|
||||
@override
|
||||
Future pick(int x, int y, void Function(PickResult p1) resultHandler) {
|
||||
// TODO: implement pick
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future removeFromScene(covariant ThermionAsset asset) {
|
||||
// TODO: implement removeFromScene
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future removeIbl() {
|
||||
// TODO: implement removeIbl
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future removeLight(ThermionEntity light) {
|
||||
// TODO: implement removeLight
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future removeSkybox() {
|
||||
// TODO: implement removeSkybox
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future render() {
|
||||
// TODO: implement render
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement rendering
|
||||
bool get rendering => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future rotateIbl(Matrix3 rotation) {
|
||||
// TODO: implement rotateIbl
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setActiveCamera(covariant Camera camera) {
|
||||
// TODO: implement setActiveCamera
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa) {
|
||||
// TODO: implement setAntiAliasing
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBackgroundColor(double r, double g, double b, double alpha) {
|
||||
// TODO: implement setBackgroundColor
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBackgroundImage(String path, {bool fillHeight = false}) {
|
||||
// TODO: implement setBackgroundImage
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBackgroundImagePosition(double x, double y, {bool clamp = false}) {
|
||||
// TODO: implement setBackgroundImagePosition
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBloom(bool enabled, double strength) {
|
||||
// TODO: implement setBloom
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setFrameRate(int framerate) {
|
||||
// TODO: implement setFrameRate
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setGridOverlayVisibility(bool visible) {
|
||||
// TODO: implement setGridOverlayVisibility
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLightDirection(ThermionEntity lightEntity, Vector3 direction) {
|
||||
// TODO: implement setLightDirection
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLightPosition(
|
||||
ThermionEntity lightEntity, double x, double y, double z) {
|
||||
// TODO: implement setLightPosition
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setPostProcessing(bool enabled) {
|
||||
// TODO: implement setPostProcessing
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setPriority(ThermionEntity entityId, int priority) {
|
||||
// TODO: implement setPriority
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRendering(bool render) {
|
||||
// TODO: implement setRendering
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setShadowType(ShadowType shadowType) {
|
||||
// TODO: implement setShadowType
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setShadowsEnabled(bool enabled) {
|
||||
// TODO: implement setShadowsEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale) {
|
||||
// TODO: implement setSoftShadowOptions
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setToneMapping(ToneMapper mapper) {
|
||||
// TODO: implement setToneMapping
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setViewFrustumCulling(bool enabled) {
|
||||
// TODO: implement setViewFrustumCulling
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setViewport(int width, int height) {
|
||||
// TODO: implement setViewport
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
// TODO: implement view
|
||||
View get view => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future setLayerVisibility(VisibilityLayers layer, bool visible) {
|
||||
// TODO: implement setLayerVisibility
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data,
|
||||
{
|
||||
String? relativeResourcePath,
|
||||
int numInstances = 1,
|
||||
bool keepData = false,
|
||||
int priority = 4,
|
||||
int layer = 0,
|
||||
bool loadResourcesAsync = false,
|
||||
}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ library thermion_flutter_js;
|
||||
|
||||
import 'dart:js_interop';
|
||||
|
||||
import '../../../../filament/src/shared_types.dart';
|
||||
import '../../../../filament/src/interface/shared_types.dart';
|
||||
|
||||
///
|
||||
/// An extension type on [JSObject] that represents a
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../thermion_viewer_base.dart';
|
||||
|
||||
class ThermionWasmCamera extends Camera {
|
||||
|
||||
final int pointer;
|
||||
|
||||
ThermionWasmCamera(this.pointer);
|
||||
|
||||
@override
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far) {
|
||||
// TODO: implement setProjectionMatrixWithCulling
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getModelMatrix() {
|
||||
// TODO: implement getModelMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLensProjection({double near = kNear, double far = kFar, double aspect = 1.0, double focalLength = kFocalLength}) {
|
||||
// TODO: implement setLensProjection
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setTransform(Matrix4 transform) {
|
||||
// TODO: implement setTransform
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
ThermionEntity getEntity() {
|
||||
// TODO: implement getEntity
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setModelMatrix(Matrix4 matrix) {
|
||||
// TODO: implement setModelMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getCullingFar() {
|
||||
// TODO: implement getCullingFar
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getFocalLength() {
|
||||
// TODO: implement getFocalLength
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getNear() {
|
||||
// TODO: implement getNear
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Matrix4> getViewMatrix() {
|
||||
// TODO: implement getViewMatrix
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setProjection(Projection projection, double left, double right, double bottom, double top, double near, double far) {
|
||||
// TODO: implement setProjection
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../../viewer.dart';
|
||||
|
||||
class ThermionWasmMaterialInstance extends MaterialInstance {
|
||||
final int pointer;
|
||||
|
||||
ThermionWasmMaterialInstance(this.pointer);
|
||||
|
||||
@override
|
||||
Future setParameterFloat2(String name, double x, double y) {
|
||||
// TODO: implement setParameterFloat2
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat(String name, double x) {
|
||||
// TODO: implement setParameterFloat
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthFunc(SamplerCompareFunction depthFunc) {
|
||||
// TODO: implement setDepthFunc
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat4(String name, double x, double y, double z, double w) {
|
||||
// TODO: implement setParameterFloat4
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterInt(String name, int value) {
|
||||
// TODO: implement setParameterInt
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthCullingEnabled(enabled) {
|
||||
// TODO: implement setDepthCullingEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthWriteEnabled(enabled) {
|
||||
// TODO: implement setDepthWriteEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilCompareFunction(SamplerCompareFunction func, [StencilFace face = StencilFace.FRONT_AND_BACK]) {
|
||||
// TODO: implement setStencilCompareFunction
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpDepthFail(StencilOperation op, [StencilFace face = StencilFace.FRONT_AND_BACK]) {
|
||||
// TODO: implement setStencilOpDepthFail
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpDepthStencilPass(StencilOperation op, [StencilFace face = StencilFace.FRONT_AND_BACK]) {
|
||||
// TODO: implement setStencilOpDepthStencilPass
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpStencilFail(StencilOperation op, [StencilFace face = StencilFace.FRONT_AND_BACK]) {
|
||||
// TODO: implement setStencilOpStencilFail
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilReferenceValue(int value, [StencilFace face = StencilFace.FRONT_AND_BACK]) {
|
||||
// TODO: implement setStencilReferenceValue
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isStencilWriteEnabled() {
|
||||
// TODO: implement isStencilWriteEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setCullingMode(CullingMode cullingMode) {
|
||||
// TODO: implement setCullingMode
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilWriteEnabled(bool enabled) {
|
||||
// TODO: implement setStencilWriteEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future dispose() {
|
||||
// TODO: implement dispose
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterBool(String name, bool value) {
|
||||
// TODO: implement setParameterBool
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat3(String name, double x, double y, double z) {
|
||||
// TODO: implement setParameterFloat3
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat3Array(String name, List<Vector3> data) {
|
||||
// TODO: implement setParameterFloat3Array
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterTexture(String name, covariant Texture texture, covariant TextureSampler sampler) {
|
||||
// TODO: implement setParameterTexture
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilReadMask(int mask) {
|
||||
// TODO: implement setStencilReadMask
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilWriteMask(int mask) {
|
||||
// TODO: implement setStencilWriteMask
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setTransparencyMode(TransparencyMode mode) {
|
||||
// TODO: implement setTransparencyMode
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -19,29 +19,29 @@
|
||||
// import 'camera.dart';
|
||||
// import 'material_instance.dart';
|
||||
|
||||
// extension type _EmscriptenModule(JSObject _) implements JSObject {
|
||||
// external JSAny? ccall(String name, String returnType,
|
||||
// JSArray<JSString> argTypes, JSArray<JSAny?> args, JSAny? opts);
|
||||
extension type _EmscriptenModule(JSObject _) implements JSObject {
|
||||
external JSAny? ccall(String name, String returnType,
|
||||
JSArray<JSString> argTypes, JSArray<JSAny?> args, JSAny? opts);
|
||||
|
||||
// external JSNumber _malloc(int numBytes);
|
||||
// external void _free(JSNumber addr);
|
||||
// external JSNumber stackAlloc(int numBytes);
|
||||
external JSNumber _malloc(int numBytes);
|
||||
external void _free(JSNumber addr);
|
||||
external JSNumber stackAlloc(int numBytes);
|
||||
|
||||
// external JSAny getValue(JSNumber addr, String llvmType);
|
||||
// external void setValue(JSNumber addr, JSNumber value, String llvmType);
|
||||
external JSAny getValue(JSNumber addr, String llvmType);
|
||||
external void setValue(JSNumber addr, JSNumber value, String llvmType);
|
||||
|
||||
// external JSString intArrayToString(JSAny ptr);
|
||||
// external JSString UTF8ToString(JSAny ptr);
|
||||
// external void stringToUTF8(
|
||||
// JSString str, JSNumber ptr, JSNumber maxBytesToWrite);
|
||||
// external void writeArrayToMemory(JSUint8Array data, JSNumber ptr);
|
||||
external JSString intArrayToString(JSAny ptr);
|
||||
external JSString UTF8ToString(JSAny ptr);
|
||||
external void stringToUTF8(
|
||||
JSString str, JSNumber ptr, JSNumber maxBytesToWrite);
|
||||
external void writeArrayToMemory(JSUint8Array data, JSNumber ptr);
|
||||
|
||||
// external JSNumber addFunction(JSFunction f, String signature);
|
||||
// external void removeFunction(JSNumber f);
|
||||
// external JSAny get ALLOC_STACK;
|
||||
// external JSAny get HEAPU32;
|
||||
// external JSAny get HEAP32;
|
||||
// }
|
||||
external JSNumber addFunction(JSFunction f, String signature);
|
||||
external void removeFunction(JSNumber f);
|
||||
external JSAny get ALLOC_STACK;
|
||||
external JSAny get HEAPU32;
|
||||
external JSAny get HEAP32;
|
||||
}
|
||||
|
||||
// typedef ThermionViewerImpl = ThermionViewerWasm;
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
// _module = module as _EmscriptenModule;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void _setAssetPathPrefix(String assetPathPrefix) {
|
||||
// _module!.ccall(
|
||||
// "thermion_dart_web_set_asset_path_prefix",
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
library thermion_viewer;
|
||||
|
||||
export 'src/thermion_viewer_base.dart';
|
||||
export '../filament/src/filament_app.dart';
|
||||
export 'src/thermion_viewer_stub.dart'
|
||||
if (dart.library.io) 'src/ffi/thermion_viewer_ffi.dart'
|
||||
if (dart.library.js_interop) 'src/web_wasm/thermion_viewer_web_wasm.dart';
|
||||
export '../filament/src/shared_types.dart';
|
||||
|
||||
export '../filament/src/interface/filament_app.dart';
|
||||
export 'src/ffi/src/thermion_viewer_ffi.dart';
|
||||
export '../filament/src/interface/shared_types.dart';
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
library filament_dart;
|
||||
|
||||
export 'dart:typed_data';
|
||||
export 'package:vector_math/vector_math_64.dart' hide Colors;
|
||||
export 'src/viewer/viewer.dart';
|
||||
export 'src/input/input.dart';
|
||||
export 'src/utils/utils.dart';
|
||||
export 'src/filament/filament.dart';
|
||||
export 'src/bindings/bindings.dart' hide Aabb2, Aabb3;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FLUTTER_FILAMENT_LOG_H
|
||||
#define FLUTTER_FILAMENT_LOG_H
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/console.h>
|
||||
#endif
|
||||
#ifdef __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
#elif defined __ANDROID__
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define Log(...) emscripten_console_logf(__VA_ARGS__);
|
||||
#else
|
||||
static void Log(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@@ -27,10 +30,9 @@ static void Log(const char *fmt, ...) {
|
||||
vprintf(fmt, args);
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||
@@ -61,5 +63,3 @@ static void Log(const char *fmt, ...) {
|
||||
#endif
|
||||
|
||||
#define ERROR(fmt, ...) Log("Error: %s:%d " fmt, __FILENAME__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
@@ -17,7 +17,7 @@ static filament::math::mat4f convert_double_to_mat4f(double* data)
|
||||
// Helper function to convert filament::math::mat4 to double4x4
|
||||
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
|
||||
{
|
||||
return double4x4{
|
||||
return double4x4 {
|
||||
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
|
||||
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
|
||||
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
|
||||
|
||||
@@ -29,7 +29,9 @@ namespace thermion
|
||||
{
|
||||
|
||||
public:
|
||||
RenderTicker(filament::Renderer *renderer) : mRenderer(renderer) { }
|
||||
RenderTicker(
|
||||
filament::Engine *engine,
|
||||
filament::Renderer *renderer) : mEngine(engine), mRenderer(renderer) { }
|
||||
~RenderTicker();
|
||||
|
||||
/// @brief
|
||||
@@ -55,6 +57,7 @@ namespace thermion
|
||||
|
||||
private:
|
||||
std::mutex mMutex;
|
||||
filament::Engine *mEngine = nullptr;
|
||||
filament::Renderer *mRenderer = nullptr;
|
||||
std::vector<AnimationManager*> mAnimationManagers;
|
||||
std::vector<std::pair<filament::SwapChain*, std::vector<filament::View*>>> mRenderable;
|
||||
|
||||
@@ -5,6 +5,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "APIExport.h"
|
||||
@@ -156,6 +157,7 @@ extern "C"
|
||||
GIZMO_TYPE_TRANSLATION,
|
||||
GIZMO_TYPE_ROTATION
|
||||
};
|
||||
typedef enum TGizmoType TGizmoType;
|
||||
|
||||
enum TPrimitiveType {
|
||||
// don't change the enums values (made to match GL)
|
||||
@@ -165,11 +167,12 @@ extern "C"
|
||||
PRIMITIVETYPE_TRIANGLES = 4, //!< triangles
|
||||
PRIMITIVETYPE_TRIANGLE_STRIP = 5 //!< triangle strip
|
||||
};
|
||||
typedef enum TPrimitiveType TPrimitiveType;
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT;
|
||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_READABLE;
|
||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
|
||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
|
||||
extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT;
|
||||
extern uint64_t TSWAP_CHAIN_CONFIG_READABLE;
|
||||
extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
|
||||
extern uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _API_EXPORT_H
|
||||
#define _API_EXPORT_H
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef IS_DLL
|
||||
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
|
||||
@@ -44,4 +44,3 @@
|
||||
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
#endif
|
||||
@@ -13,37 +13,38 @@ enum TProjection {
|
||||
Perspective,
|
||||
Orthographic
|
||||
};
|
||||
typedef enum TProjection TProjection;
|
||||
|
||||
// Camera methods
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getProjectionMatrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *camera, double* out);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjectionMatrix(TCamera *camera, double *matrix, double near, double far);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjectionFromFov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_lookAt(TCamera* camera, double3 eye, double3 focus, double3 up);
|
||||
void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
||||
double4x4 Camera_getModelMatrix(TCamera *const camera);
|
||||
double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||
double4x4 Camera_getProjectionMatrix(TCamera *const camera);
|
||||
double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera);
|
||||
void Camera_getFrustum(TCamera *camera, double* out);
|
||||
void Camera_setProjectionMatrix(TCamera *camera, double *matrix, double near, double far);
|
||||
void Camera_setProjectionFromFov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
||||
double Camera_getFocalLength(TCamera *const camera);
|
||||
double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||
double4x4 Camera_getModelMatrix(TCamera* camera);
|
||||
void Camera_lookAt(TCamera* camera, double3 eye, double3 focus, double3 up);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE float Camera_getFov(TCamera *camera, bool horizontal);
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocusDistance(TCamera *camera);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setFocusDistance(TCamera *camera, float focusDistance);
|
||||
double Camera_getNear(TCamera *camera);
|
||||
double Camera_getCullingFar(TCamera *camera);
|
||||
float Camera_getFov(TCamera *camera, bool horizontal);
|
||||
double Camera_getFocusDistance(TCamera *camera);
|
||||
void Camera_setFocusDistance(TCamera *camera, float focusDistance);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(
|
||||
void Camera_setCustomProjectionWithCulling(
|
||||
TCamera* camera,
|
||||
double4x4 projectionMatrix,
|
||||
double near,
|
||||
double far
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
|
||||
void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix);
|
||||
void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
||||
EntityId Camera_getEntity(TCamera* camera);
|
||||
void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
|
||||
double bottom, double top,
|
||||
double near, double far);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ enum TBackend {
|
||||
BACKEND_METAL = 3, //!< Selects the Metal driver if the platform supports it (default on MacOS/iOS).
|
||||
BACKEND_NOOP = 4, //!< Selects the no-op driver for testing purposes.
|
||||
};
|
||||
typedef enum TBackend TBackend;
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
|
||||
TBackend backend,
|
||||
@@ -50,6 +51,7 @@ EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTex
|
||||
EMSCRIPTEN_KEEPALIVE TFence *Engine_createFence(TEngine *tEngine);
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyFence(TEngine *tEngine, TFence *tFence);
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWait(TEngine *tEngine);
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_execute(TEngine *tEngine);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Engine_buildMaterial(TEngine *tEngine, const uint8_t* materialData, size_t length);
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tMaterial);
|
||||
|
||||
@@ -13,9 +13,11 @@ extern "C"
|
||||
|
||||
enum TGizmoAxis { X, Y, Z };
|
||||
enum TGizmoPickResultType { AxisX, AxisY, AxisZ, Parent, None };
|
||||
typedef enum TGizmoPickResultType TGizmoPickResultType;
|
||||
typedef enum TGizmoAxis TGizmoAxis;
|
||||
|
||||
typedef void (*GizmoPickCallback)(TGizmoPickResultType resultType, float x, float y, float z);
|
||||
|
||||
void Gizmo_dummy(TGizmoPickResultType t);
|
||||
EMSCRIPTEN_KEEPALIVE TGizmo *Gizmo_create(
|
||||
TEngine *tEngine,
|
||||
TGltfAssetLoader *assetLoader,
|
||||
|
||||
@@ -16,6 +16,7 @@ extern "C"
|
||||
LIGHT_TYPE_FOCUSED_SPOT,
|
||||
LIGHT_TYPE_SPOT
|
||||
};
|
||||
typedef enum TLightType TLightType;
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z);
|
||||
EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z);
|
||||
|
||||
@@ -21,6 +21,7 @@ extern "C"
|
||||
A, //!< Always. Depth / stencil testing is deactivated.
|
||||
N //!< Never. The depth / stencil test always fails.
|
||||
};
|
||||
typedef enum TSamplerCompareFunc TSamplerCompareFunc;
|
||||
|
||||
// StencilOperation equivalent
|
||||
enum TStencilOperation
|
||||
@@ -34,6 +35,7 @@ extern "C"
|
||||
DECR_WRAP, // Decrement the current value without saturation
|
||||
INVERT // Invert the current value
|
||||
};
|
||||
typedef enum TStencilOperation TStencilOperation;
|
||||
|
||||
enum TStencilFace
|
||||
{
|
||||
@@ -41,6 +43,7 @@ extern "C"
|
||||
STENCIL_FACE_BACK = 2,
|
||||
STENCIL_FACE_FRONT_AND_BACK = 3
|
||||
};
|
||||
typedef enum TStencilFace TStencilFace;
|
||||
|
||||
enum TCullingMode
|
||||
{
|
||||
@@ -49,6 +52,7 @@ extern "C"
|
||||
CULLING_MODE_BACK,
|
||||
CULLING_MODE_FRONT_AND_BACK
|
||||
};
|
||||
typedef enum TCullingMode TCullingMode;
|
||||
|
||||
enum TTransparencyMode {
|
||||
//! the transparent object is drawn honoring the raster state
|
||||
@@ -66,6 +70,7 @@ extern "C"
|
||||
*/
|
||||
TWO_PASSES_TWO_SIDES
|
||||
};
|
||||
typedef enum TTransparencyMode TTransparencyMode;
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine);
|
||||
|
||||
@@ -8,7 +8,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer);
|
||||
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TEngine *tEngine, TRenderer *tRenderer);
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_destroy(TRenderTicker *tRenderTicker);
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_addAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_removeAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "APIExport.h"
|
||||
#include "APIBoundaryTypes.h"
|
||||
#include "TMaterialInstance.h"
|
||||
#include "TTexture.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
||||
@@ -20,6 +20,8 @@ enum TTextureSamplerType
|
||||
SAMPLER_CUBEMAP_ARRAY=5
|
||||
};
|
||||
|
||||
typedef enum TTextureSamplerType TTextureSamplerType;
|
||||
|
||||
enum TTextureFormat
|
||||
{
|
||||
// 8-bits per element
|
||||
@@ -157,6 +159,7 @@ enum TTextureFormat
|
||||
TEXTUREFORMAT_RGBA_BPTC_UNORM, // BC7
|
||||
TEXTUREFORMAT_SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
|
||||
};
|
||||
typedef enum TTextureFormat TTextureFormat;
|
||||
|
||||
//! Pixel Data Format
|
||||
enum TPixelDataFormat {
|
||||
@@ -173,6 +176,7 @@ enum TPixelDataFormat {
|
||||
PIXELDATAFORMAT_DEPTH_STENCIL, //!< Two Depth (24-bits) + Stencil (8-bits) channels
|
||||
PIXELDATAFORMAT_ALPHA //! One Alpha channel, float
|
||||
};
|
||||
typedef enum TPixelDataFormat TPixelDataFormat;
|
||||
|
||||
enum TPixelDataType {
|
||||
PIXELDATATYPE_UBYTE, //!< unsigned byte
|
||||
@@ -188,6 +192,7 @@ enum TPixelDataType {
|
||||
PIXELDATATYPE_USHORT_565, //!< unsigned int (16-bit), encodes 3 RGB channels
|
||||
PIXELDATATYPE_UINT_2_10_10_10_REV, //!< unsigned normalized 10 bits RGB, 2 bits alpha
|
||||
};
|
||||
typedef enum TPixelDataType TPixelDataType;
|
||||
|
||||
enum TTextureUsage {
|
||||
TEXTURE_USAGE_NONE = 0x0000,
|
||||
@@ -202,6 +207,7 @@ enum TTextureUsage {
|
||||
TEXTURE_USAGE_PROTECTED = 0x0100, //!< Texture can be used the destination of a blit()
|
||||
TEXTURE_USAGE_DEFAULT = TEXTURE_USAGE_UPLOADABLE | TEXTURE_USAGE_SAMPLEABLE //!< Default texture usage
|
||||
};
|
||||
typedef enum TTextureUsage TTextureUsage;
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TTexture *Texture_build(TEngine *engine,
|
||||
uint32_t width,
|
||||
@@ -268,6 +274,7 @@ enum TSamplerWrapMode {
|
||||
WRAP_REPEAT, // Repeat wrapping mode
|
||||
WRAP_MIRRORED_REPEAT // Mirrored repeat wrapping mode
|
||||
};
|
||||
typedef enum TSamplerWrapMode TSamplerWrapMode;
|
||||
|
||||
enum TSamplerMinFilter {
|
||||
FILTER_NEAREST, // Nearest filtering
|
||||
@@ -277,16 +284,19 @@ enum TSamplerMinFilter {
|
||||
FILTER_NEAREST_MIPMAP_LINEAR, // Nearest mipmap linear filtering
|
||||
FILTER_LINEAR_MIPMAP_LINEAR // Linear mipmap linear filtering
|
||||
};
|
||||
typedef enum TSamplerMinFilter TSamplerMinFilter;
|
||||
|
||||
enum TSamplerMagFilter {
|
||||
MAG_FILTER_NEAREST, // Nearest filtering
|
||||
MAG_FILTER_LINEAR // Linear filtering
|
||||
};
|
||||
typedef enum TSamplerMagFilter TSamplerMagFilter;
|
||||
|
||||
enum TSamplerCompareMode {
|
||||
COMPARE_MODE_NONE, // No comparison
|
||||
COMPARE_MODE_COMPARE_TO_TEXTURE // Compare to texture
|
||||
};
|
||||
typedef enum TSamplerCompareMode TSamplerCompareMode;
|
||||
|
||||
typedef TSamplerCompareFunc TTextureSamplerCompareFunc ;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ enum TToneMapping
|
||||
FILMIC,
|
||||
LINEAR
|
||||
};
|
||||
typedef enum TToneMapping TToneMapping;
|
||||
|
||||
// copied from Options.h
|
||||
enum TQualityLevel {
|
||||
@@ -31,11 +32,13 @@ enum TQualityLevel {
|
||||
HIGH,
|
||||
ULTRA
|
||||
};
|
||||
typedef enum TQualityLevel TQualityLevel;
|
||||
|
||||
enum TBlendMode {
|
||||
OPAQUE,
|
||||
TRANSLUCENT
|
||||
};
|
||||
typedef enum TBlendMode TBlendMode;
|
||||
|
||||
// View
|
||||
EMSCRIPTEN_KEEPALIVE TViewport View_getViewport(TView *view);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "TEngine.h"
|
||||
#include "TView.h"
|
||||
#include "TTexture.h"
|
||||
#include "TMaterialProvider.h"
|
||||
@@ -10,20 +11,20 @@ namespace thermion
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void (*VoidCallback)();
|
||||
typedef int32_t EntityId;
|
||||
typedef void (*FilamentRenderCallback)(void *const owner);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void RenderThread_create();
|
||||
EMSCRIPTEN_KEEPALIVE void RenderThread_destroy();
|
||||
EMSCRIPTEN_KEEPALIVE void RenderThread_requestFrame(void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void RenderThread_setRenderTicker(TRenderTicker *tRenderTicker);
|
||||
EMSCRIPTEN_KEEPALIVE void RenderThread_addTask(void (*task)());
|
||||
void RenderThread_create();
|
||||
void RenderThread_destroy();
|
||||
void RenderThread_requestFrameAsync();
|
||||
void RenderThread_setRenderTicker(TRenderTicker *tRenderTicker);
|
||||
void RenderThread_addTask(void (*task)());
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
|
||||
void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, VoidCallback onComplete);
|
||||
void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createRenderThread(
|
||||
void Engine_createRenderThread(
|
||||
TBackend backend,
|
||||
void* platform,
|
||||
void* sharedContext,
|
||||
@@ -31,22 +32,22 @@ namespace thermion
|
||||
bool disableHandleUseAfterFreeCheck,
|
||||
void (*onComplete)(TEngine *)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createSwapChainRenderThread(TEngine *tEngine, void *window, uint64_t flags, void (*onComplete)(TSwapChain *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createHeadlessSwapChainRenderThread(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags, void (*onComplete)(TSwapChain *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createCameraRenderThread(TEngine* tEngine, void (*onComplete)(TCamera *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createViewRenderThread(TEngine *tEngine, void (*onComplete)(TView *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyRenderThread(TEngine *tEngine, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine,
|
||||
void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *));
|
||||
void Engine_createSwapChainRenderThread(TEngine *tEngine, void *window, uint64_t flags, void (*onComplete)(TSwapChain *));
|
||||
void Engine_createHeadlessSwapChainRenderThread(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags, void (*onComplete)(TSwapChain *));
|
||||
void Engine_createCameraRenderThread(TEngine* tEngine, void (*onComplete)(TCamera *));
|
||||
void Engine_createViewRenderThread(TEngine *tEngine, void (*onComplete)(TView *));
|
||||
void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
|
||||
void Engine_destroyRenderThread(TEngine *tEngine, VoidCallback onComplete);
|
||||
void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, VoidCallback onComplete);
|
||||
void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, VoidCallback onComplete);
|
||||
void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, VoidCallback onComplete);
|
||||
void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, VoidCallback onComplete);
|
||||
void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, VoidCallback onComplete);
|
||||
void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, VoidCallback onComplete);
|
||||
void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, VoidCallback onComplete);
|
||||
void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, VoidCallback onComplete);
|
||||
void Texture_buildRenderThread(TEngine *engine,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
@@ -58,19 +59,20 @@ namespace thermion
|
||||
void (*onComplete)(TTexture*)
|
||||
);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWaitRenderThead(TEngine *tEngine, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_buildSkyboxRenderThread(TEngine *tEngine, uint8_t *skyboxData, size_t length, void (*onComplete)(TSkybox *), void (*onTextureUploadComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightRenderThread(TEngine *tEngine, uint8_t *iblData, size_t length, float intensity, void (*onComplete)(TIndirectLight *), void (*onTextureUploadComplete)());
|
||||
void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, VoidCallback onComplete);
|
||||
void Engine_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
|
||||
void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, VoidCallback onComplete);
|
||||
void Engine_flushAndWaitRenderThread(TEngine *tEngine, VoidCallback onComplete);
|
||||
void Engine_executeRenderThread(TEngine *tEngine, VoidCallback onComplete);
|
||||
void Engine_buildSkyboxRenderThread(TEngine *tEngine, uint8_t *skyboxData, size_t length, void (*onComplete)(TSkybox *), void (*onTextureUploadComplete)());
|
||||
void Engine_buildIndirectLightRenderThread(TEngine *tEngine, uint8_t *iblData, size_t length, float intensity, void (*onComplete)(TIndirectLight *), void (*onTextureUploadComplete)());
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));
|
||||
EMSCRIPTEN_KEEPALIVE void Renderer_endFrameRenderThread(TRenderer *tRenderer, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Renderer_readPixelsRenderThread(
|
||||
void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, VoidCallback onComplete);
|
||||
void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));
|
||||
void Renderer_endFrameRenderThread(TRenderer *tRenderer, VoidCallback onComplete);
|
||||
void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete);
|
||||
void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete);
|
||||
void Renderer_readPixelsRenderThread(
|
||||
TRenderer *tRenderer,
|
||||
TView *tView,
|
||||
TRenderTarget *tRenderTarget,
|
||||
@@ -78,29 +80,29 @@ namespace thermion
|
||||
TPixelDataType tPixelDataType,
|
||||
uint8_t *out,
|
||||
size_t outLength,
|
||||
void (*onComplete)());
|
||||
VoidCallback onComplete);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *));
|
||||
EMSCRIPTEN_KEEPALIVE void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
|
||||
EMSCRIPTEN_KEEPALIVE void Material_createGizmoMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
|
||||
void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *));
|
||||
void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
|
||||
void Material_createGizmoMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void ColorGrading_createRenderThread(TEngine *tEngine, TToneMapping toneMapping, void (*callback)(TColorGrading *));
|
||||
EMSCRIPTEN_KEEPALIVE void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, void (*callback)());
|
||||
void ColorGrading_createRenderThread(TEngine *tEngine, TToneMapping toneMapping, void (*callback)(TColorGrading *));
|
||||
void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, VoidCallback onComplete);
|
||||
void View_setBloomRenderThread(TView *tView, bool enabled, double strength, VoidCallback onComplete);
|
||||
void View_setCameraRenderThread(TView *tView, TCamera *tCamera, VoidCallback onComplete);
|
||||
|
||||
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
|
||||
void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, VoidCallback onComplete);
|
||||
void SceneAsset_createFromFilamentAssetRenderThread(
|
||||
TEngine *tEngine,
|
||||
TGltfAssetLoader *tAssetLoader,
|
||||
TNameComponentManager *tNameComponentManager,
|
||||
TFilamentAsset *tFilamentAsset,
|
||||
void (*onComplete)(TSceneAsset *)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
|
||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_createGeometryRenderThread(
|
||||
void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
|
||||
void SceneAsset_createGeometryRenderThread(
|
||||
TEngine *tEngine,
|
||||
float *vertices,
|
||||
uint32_t numVertices,
|
||||
@@ -115,14 +117,14 @@ namespace thermion
|
||||
int materialInstanceCount,
|
||||
void (*callback)(TSceneAsset *)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialProvider_createMaterialInstanceRenderThread(TMaterialProvider *tMaterialProvider, TMaterialKey *tKey, void (*callback)(TMaterialInstance *));
|
||||
void MaterialProvider_createMaterialInstanceRenderThread(TMaterialProvider *tMaterialProvider, TMaterialKey *tKey, void (*callback)(TMaterialInstance *));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(
|
||||
void AnimationManager_updateBoneMatricesRenderThread(
|
||||
TAnimationManager *tAnimationManager,
|
||||
TSceneAsset *sceneAsset,
|
||||
void (*callback)(bool));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setMorphTargetWeightsRenderThread(
|
||||
void AnimationManager_setMorphTargetWeightsRenderThread(
|
||||
TAnimationManager *tAnimationManager,
|
||||
EntityId entityId,
|
||||
const float *const morphData,
|
||||
@@ -130,16 +132,16 @@ namespace thermion
|
||||
void (*callback)(bool));
|
||||
|
||||
// Image methods
|
||||
EMSCRIPTEN_KEEPALIVE void Image_createEmptyRenderThread(uint32_t width, uint32_t height, uint32_t channel, void (*onComplete)(TLinearImage *));
|
||||
EMSCRIPTEN_KEEPALIVE void Image_decodeRenderThread(uint8_t* data, size_t length, const char* name, void (*onComplete)(TLinearImage *));
|
||||
EMSCRIPTEN_KEEPALIVE void Image_getBytesRenderThread(TLinearImage *tLinearImage, void (*onComplete)(float *));
|
||||
EMSCRIPTEN_KEEPALIVE void Image_destroyRenderThread(TLinearImage *tLinearImage, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Image_getWidthRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
EMSCRIPTEN_KEEPALIVE void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
EMSCRIPTEN_KEEPALIVE void Image_getChannelsRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
void Image_createEmptyRenderThread(uint32_t width, uint32_t height, uint32_t channel, void (*onComplete)(TLinearImage *));
|
||||
void Image_decodeRenderThread(uint8_t* data, size_t length, const char* name, void (*onComplete)(TLinearImage *));
|
||||
void Image_getBytesRenderThread(TLinearImage *tLinearImage, void (*onComplete)(float *));
|
||||
void Image_destroyRenderThread(TLinearImage *tLinearImage, VoidCallback onComplete);
|
||||
void Image_getWidthRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
void Image_getChannelsRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_loadImageRenderThread(
|
||||
void Texture_loadImageRenderThread(
|
||||
TEngine *tEngine,
|
||||
TTexture *tTexture,
|
||||
TLinearImage *tImage,
|
||||
@@ -147,7 +149,7 @@ namespace thermion
|
||||
TPixelDataType pixelDataType,
|
||||
void (*onComplete)(bool)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_setImageRenderThread(
|
||||
void Texture_setImageRenderThread(
|
||||
TEngine *tEngine,
|
||||
TTexture *tTexture,
|
||||
uint32_t level,
|
||||
@@ -160,7 +162,7 @@ namespace thermion
|
||||
uint32_t pixelDataType,
|
||||
void (*onComplete)(bool)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread(
|
||||
void Texture_setImageWithDepthRenderThread(
|
||||
TEngine *tEngine,
|
||||
TTexture *tTexture,
|
||||
uint32_t level,
|
||||
@@ -177,8 +179,8 @@ namespace thermion
|
||||
uint32_t pixelDataType,
|
||||
void (*onComplete)(bool)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *));
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_createRenderThread(
|
||||
void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *));
|
||||
void RenderTarget_createRenderThread(
|
||||
TEngine *tEngine,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
@@ -186,16 +188,16 @@ namespace thermion
|
||||
TTexture *depth,
|
||||
void (*onComplete)(TRenderTarget *)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_destroyRenderThread(
|
||||
void RenderTarget_destroyRenderThread(
|
||||
TEngine *tEngine,
|
||||
TRenderTarget *tRenderTarget,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
|
||||
|
||||
// TextureSampler methods
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*));
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_createWithFilteringRenderThread(
|
||||
void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*));
|
||||
void TextureSampler_createWithFilteringRenderThread(
|
||||
TSamplerMinFilter minFilter,
|
||||
TSamplerMagFilter magFilter,
|
||||
TSamplerWrapMode wrapS,
|
||||
@@ -203,53 +205,53 @@ namespace thermion
|
||||
TSamplerWrapMode wrapR,
|
||||
void (*onComplete)(TTextureSampler*)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_createWithComparisonRenderThread(
|
||||
void TextureSampler_createWithComparisonRenderThread(
|
||||
TSamplerCompareMode compareMode,
|
||||
TSamplerCompareFunc compareFunc,
|
||||
void (*onComplete)(TTextureSampler*)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMinFilterRenderThread(
|
||||
void TextureSampler_setMinFilterRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
TSamplerMinFilter filter,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMagFilterRenderThread(
|
||||
void TextureSampler_setMagFilterRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
TSamplerMagFilter filter,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeSRenderThread(
|
||||
void TextureSampler_setWrapModeSRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
TSamplerWrapMode mode,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeTRenderThread(
|
||||
void TextureSampler_setWrapModeTRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
TSamplerWrapMode mode,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeRRenderThread(
|
||||
void TextureSampler_setWrapModeRRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
TSamplerWrapMode mode,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setAnisotropyRenderThread(
|
||||
void TextureSampler_setAnisotropyRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
double anisotropy,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setCompareModeRenderThread(
|
||||
void TextureSampler_setCompareModeRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
TSamplerCompareMode mode,
|
||||
TTextureSamplerCompareFunc func,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_destroyRenderThread(
|
||||
void TextureSampler_destroyRenderThread(
|
||||
TTextureSampler* sampler,
|
||||
void (*onComplete)()
|
||||
VoidCallback onComplete
|
||||
);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setBoneTransformRenderThread(
|
||||
void AnimationManager_setBoneTransformRenderThread(
|
||||
TAnimationManager *tAnimationManager,
|
||||
EntityId asset,
|
||||
int skinIndex,
|
||||
@@ -257,18 +259,18 @@ namespace thermion
|
||||
const float *const transform,
|
||||
void (*callback)(bool));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, void (*callback)());
|
||||
void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, VoidCallback onComplete);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncUpdateLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader);
|
||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncGetLoadProgressRenderThread(TGltfResourceLoader *tGltfResourceLoader, void (*callback)(float));
|
||||
void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
|
||||
void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
|
||||
void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, VoidCallback onComplete);
|
||||
void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
||||
void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, VoidCallback onComplete);
|
||||
void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
||||
void GltfResourceLoader_asyncUpdateLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader);
|
||||
void GltfResourceLoader_asyncGetLoadProgressRenderThread(TGltfResourceLoader *tGltfResourceLoader, void (*callback)(float));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread(
|
||||
void GltfAssetLoader_loadRenderThread(
|
||||
TEngine *tEngine,
|
||||
TGltfAssetLoader *tAssetLoader,
|
||||
uint8_t *data,
|
||||
@@ -276,8 +278,8 @@ namespace thermion
|
||||
uint8_t numInstances,
|
||||
void (*callback)(TFilamentAsset *)
|
||||
);
|
||||
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, void (*callback)());
|
||||
EMSCRIPTEN_KEEPALIVE void Gizmo_createRenderThread(
|
||||
void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, VoidCallback onComplete);
|
||||
void Gizmo_createRenderThread(
|
||||
TEngine *tEngine,
|
||||
TGltfAssetLoader *tAssetLoader,
|
||||
TGltfResourceLoader *tGltfResourceLoader,
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern const uint8_t CAPTURE_UV_PACKAGE[];
|
||||
extern int CAPTURE_UV_CAPTURE_UV_OFFSET;
|
||||
extern int CAPTURE_UV_CAPTURE_UV_SIZE;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#define CAPTURE_UV_CAPTURE_UV_DATA (CAPTURE_UV_PACKAGE + CAPTURE_UV_CAPTURE_UV_OFFSET)
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern const uint8_t GRID_PACKAGE[];
|
||||
extern int GRID_GRID_OFFSET;
|
||||
extern int GRID_GRID_SIZE;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#define GRID_GRID_DATA (GRID_PACKAGE + GRID_GRID_OFFSET)
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user