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>
|
<html>
|
||||||
|
|
||||||
<head>
|
<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">
|
<base href="$FLUTTER_BASE_HREF">
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
@@ -37,12 +24,17 @@
|
|||||||
const serviceWorkerVersion = null;
|
const serviceWorkerVersion = null;
|
||||||
</script>
|
</script>
|
||||||
<script src="flutter.js" defer></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>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<canvas id="canvas"></canvas>
|
|
||||||
<div id="flutter-container"></div>
|
<div id="flutter-container"></div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('load', function (ev) {
|
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 . --target imageio --config Release
|
||||||
cmake --build . --config Debug
|
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:
|
headers:
|
||||||
entry-points:
|
entry-points:
|
||||||
- '../native/include/c_api/*.h'
|
- '../native/include/c_api/*.h'
|
||||||
- '../native/include/ResourceBuffer.h'
|
|
||||||
include-directives:
|
include-directives:
|
||||||
- '../native/include/c_api/*.h'
|
- '../native/include/c_api/*.h'
|
||||||
- '../native/include/ResourceBuffer.h'
|
|
||||||
ffi-native:
|
ffi-native:
|
||||||
assetId: package:thermion_dart/thermion_dart.dart
|
assetId: package:thermion_dart/thermion_dart.dart
|
||||||
ignore-source-errors: true
|
ignore-source-errors: true
|
||||||
@@ -16,7 +14,4 @@ functions:
|
|||||||
enums:
|
enums:
|
||||||
as-int:
|
as-int:
|
||||||
include:
|
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:
|
headers:
|
||||||
entry-points:
|
entry-points:
|
||||||
- '../native/web/include/ThermionFlutterWebApi.h'
|
- '../native/web/include/ThermionWebApi.h'
|
||||||
- '../native/include/ThermionDartFFIApi.h'
|
- '../native/include/c_api/*.h'
|
||||||
- '../native/include/ThermionDartApi.h'
|
|
||||||
- '../native/include/ResourceBuffer.h'
|
|
||||||
include-directives:
|
include-directives:
|
||||||
- '../native/web/include/ThermionFlutterWebApi.h'
|
- '../native/web/include/ThermionWebApi.h'
|
||||||
- '../native/include/ThermionDartFFIApi.h'
|
- '../native/include/c_api/*.h'
|
||||||
- '../native/include/ThermionDartApi.h'
|
|
||||||
- '../native/include/ResourceBuffer.h'
|
|
||||||
compiler-opts:
|
compiler-opts:
|
||||||
- "-D__EMSCRIPTEN__"
|
- "-D__EMSCRIPTEN__"
|
||||||
structs:
|
structs:
|
||||||
@@ -20,9 +16,8 @@ unions:
|
|||||||
dependency-only: opaque
|
dependency-only: opaque
|
||||||
exclude:
|
exclude:
|
||||||
- '.*'
|
- '.*'
|
||||||
globals:
|
|
||||||
exclude:
|
|
||||||
- '.*'
|
|
||||||
ffi-native:
|
|
||||||
assetId: thermion_dart
|
|
||||||
ignore-source-errors: true
|
ignore-source-errors: true
|
||||||
|
enums:
|
||||||
|
as-int:
|
||||||
|
include:
|
||||||
|
- .*
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:archive/archive.dart';
|
import 'package:archive/archive.dart';
|
||||||
|
import 'package:code_assets/code_assets.dart';
|
||||||
|
import 'package:hooks/hooks.dart';
|
||||||
import 'package:logging/logging.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:native_toolchain_c/native_toolchain_c.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ void main(List<String> args) async {
|
|||||||
final packageName = input.packageName;
|
final packageName = input.packageName;
|
||||||
final outputDirectory = input.outputDirectory;
|
final outputDirectory = input.outputDirectory;
|
||||||
final targetOS = config.code.targetOS;
|
final targetOS = config.code.targetOS;
|
||||||
|
|
||||||
final targetArchitecture = config.code.targetArchitecture;
|
final targetArchitecture = config.code.targetArchitecture;
|
||||||
var logPath = path.join(
|
var logPath = path.join(
|
||||||
pkgRootFilePath, ".dart_tool", "thermion_dart", "log", "build.log");
|
pkgRootFilePath, ".dart_tool", "thermion_dart", "log", "build.log");
|
||||||
@@ -258,9 +260,8 @@ void main(List<String> args) async {
|
|||||||
package: "thermion_dart",
|
package: "thermion_dart",
|
||||||
name: "libc++_shared.so",
|
name: "libc++_shared.so",
|
||||||
linkMode: DynamicLoadingBundled(),
|
linkMode: DynamicLoadingBundled(),
|
||||||
os: targetOS,
|
|
||||||
file: stlPath.uri,
|
file: stlPath.uri,
|
||||||
architecture: targetArchitecture);
|
);
|
||||||
|
|
||||||
output.assets.addEncodedAsset(libcpp.encode());
|
output.assets.addEncodedAsset(libcpp.encode());
|
||||||
}
|
}
|
||||||
@@ -274,9 +275,8 @@ void main(List<String> args) async {
|
|||||||
package: packageName,
|
package: packageName,
|
||||||
name: "thermion_dart.lib",
|
name: "thermion_dart.lib",
|
||||||
linkMode: DynamicLoadingBundled(),
|
linkMode: DynamicLoadingBundled(),
|
||||||
os: targetOS,
|
|
||||||
file: importLib.uri,
|
file: importLib.uri,
|
||||||
architecture: targetArchitecture);
|
);
|
||||||
output.assets.addEncodedAsset(libthermion.encode());
|
output.assets.addEncodedAsset(libthermion.encode());
|
||||||
|
|
||||||
for (final dir in ["windows/vulkan"]) {
|
for (final dir in ["windows/vulkan"]) {
|
||||||
@@ -298,9 +298,8 @@ void main(List<String> args) async {
|
|||||||
package: packageName,
|
package: packageName,
|
||||||
name: "include/$dir/${path.basename(file.path)}",
|
name: "include/$dir/${path.basename(file.path)}",
|
||||||
linkMode: DynamicLoadingBundled(),
|
linkMode: DynamicLoadingBundled(),
|
||||||
os: targetOS,
|
|
||||||
file: file.uri,
|
file: file.uri,
|
||||||
architecture: targetArchitecture);
|
);
|
||||||
output.assets.addEncodedAsset(include.encode());
|
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:async';
|
||||||
import 'dart:ffi';
|
import 'dart:io';
|
||||||
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
|
||||||
export 'package:ffi/ffi.dart';
|
export 'package:ffi/ffi.dart';
|
||||||
export 'dart:ffi';
|
export 'dart:ffi' hide Size;
|
||||||
export 'thermion_dart.g.dart';
|
|
||||||
|
|
||||||
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 {
|
class NativeLibrary {
|
||||||
await function.call(ptr);
|
static void initBindings(String name) {
|
||||||
allocator.free(ptr);
|
throw Exception();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> withVoidCallback2(Function() func) async {
|
typedef IntPtrList = Int64List;
|
||||||
final completer = Completer();
|
typedef Float64 = Double;
|
||||||
void Function() callback = () {
|
typedef PointerClass<T extends NativeType> = Pointer<T>;
|
||||||
func.call();
|
typedef VoidPointerClass = Pointer<Void>;
|
||||||
completer.complete();
|
|
||||||
};
|
class CallbackHolder<T extends Function> {
|
||||||
final nativeCallable = NativeCallable<Void Function()>.listener(callback);
|
final NativeCallable<T> nativeCallable;
|
||||||
RenderThread_addTask(nativeCallable.nativeFunction);
|
|
||||||
await completer.future;
|
Pointer<NativeFunction<T>> get pointer => nativeCallable.nativeFunction;
|
||||||
nativeCallable.close();
|
|
||||||
|
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(
|
Future<void> withVoidCallback(
|
||||||
@@ -75,7 +135,8 @@ Future<double> withFloatCallback(
|
|||||||
void Function(double) callback = (double result) {
|
void Function(double) callback = (double result) {
|
||||||
completer.complete(result);
|
completer.complete(result);
|
||||||
};
|
};
|
||||||
final nativeCallable = NativeCallable<Void Function(Float)>.listener(callback);
|
final nativeCallable =
|
||||||
|
NativeCallable<Void Function(Float)>.listener(callback);
|
||||||
func.call(nativeCallable.nativeFunction);
|
func.call(nativeCallable.nativeFunction);
|
||||||
await completer.future;
|
await completer.future;
|
||||||
nativeCallable.close();
|
nativeCallable.close();
|
||||||
@@ -127,3 +188,15 @@ Future<String> withCharPtrCallback(
|
|||||||
nativeCallable.close();
|
nativeCallable.close();
|
||||||
return completer.future;
|
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/interface/filament_app.dart';
|
||||||
export 'src/engine.dart';
|
export 'src/interface/engine.dart';
|
||||||
export 'src/layers.dart';
|
export 'src/interface/layers.dart';
|
||||||
export 'src/light_options.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:vector_math/vector_math_64.dart' as v64;
|
||||||
import 'package:animation_tools_dart/src/bone_animation_data.dart';
|
import 'package:animation_tools_dart/src/bone_animation_data.dart';
|
||||||
import 'package:animation_tools_dart/src/morph_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/filament/src/interface/layers.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class BackgroundImage extends ThermionAsset {
|
class BackgroundImage extends ThermionAsset {
|
||||||
@@ -47,10 +47,12 @@ class BackgroundImage extends ThermionAsset {
|
|||||||
var backgroundImage =
|
var backgroundImage =
|
||||||
await viewer.createGeometry(GeometryHelper.fullscreenQuad());
|
await viewer.createGeometry(GeometryHelper.fullscreenQuad());
|
||||||
await imageMaterialInstance.setParameterInt("showImage", 0);
|
await imageMaterialInstance.setParameterInt("showImage", 0);
|
||||||
|
var transform = Matrix4.identity();
|
||||||
|
|
||||||
await imageMaterialInstance.setParameterMat4(
|
await imageMaterialInstance.setParameterMat4(
|
||||||
"transform", Matrix4.identity());
|
"transform", transform);
|
||||||
|
|
||||||
backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
await backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
||||||
await scene.add(backgroundImage as FFIAsset);
|
await scene.add(backgroundImage as FFIAsset);
|
||||||
return BackgroundImage._(
|
return BackgroundImage._(
|
||||||
backgroundImage, scene, null, null, imageMaterialInstance);
|
backgroundImage, scene, null, null, imageMaterialInstance);
|
||||||
@@ -1,13 +1,8 @@
|
|||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package: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/utils/src/matrix.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_material.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/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||||
|
|
||||||
@@ -52,15 +47,31 @@ class FFIAsset extends ThermionAsset {
|
|||||||
entity = SceneAsset_getEntity(asset);
|
entity = SceneAsset_getEntity(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Int32List? _childEntities;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<List<ThermionEntity>> getChildEntities() async {
|
Future<List<ThermionEntity>> getChildEntities() async {
|
||||||
var count = SceneAsset_getChildEntityCount(asset);
|
if (_childEntities == null) {
|
||||||
var children = Int32List(count);
|
var count = SceneAsset_getChildEntityCount(asset);
|
||||||
SceneAsset_getChildEntities(asset, children.address);
|
var childEntities = Int32List(count);
|
||||||
return children;
|
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
|
@override
|
||||||
Future<FFIAsset> createInstance(
|
Future<FFIAsset> createInstance(
|
||||||
{covariant List<MaterialInstance>? materialInstances = null}) async {
|
{covariant List<MaterialInstance>? materialInstances = null}) async {
|
||||||
var created = await withPointerCallback<TSceneAsset>((cb) {
|
var ptrList = IntPtrList(materialInstances?.length ?? 0);
|
||||||
var ptrList = Int64List(materialInstances?.length ?? 0);
|
late Pointer stackPtr;
|
||||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
if (FILAMENT_WASM) {
|
||||||
ptrList.setRange(
|
//stackPtr = stackSave();
|
||||||
0,
|
}
|
||||||
materialInstances.length,
|
|
||||||
materialInstances
|
|
||||||
.cast<FFIMaterialInstance>()
|
|
||||||
.map((mi) => mi.pointer.address)
|
|
||||||
.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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(
|
SceneAsset_createInstanceRenderThread(
|
||||||
asset,
|
asset, ptrList.address.cast(), materialInstances?.length ?? 0, cb);
|
||||||
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
|
||||||
materialInstances?.length ?? 0,
|
|
||||||
cb);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
ptrList.free();
|
||||||
|
}
|
||||||
|
|
||||||
if (created == FILAMENT_ASSET_ERROR) {
|
if (created == FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("Failed to create instance");
|
throw Exception("Failed to create instance");
|
||||||
}
|
}
|
||||||
@@ -251,6 +270,13 @@ class FFIAsset extends ThermionAsset {
|
|||||||
///
|
///
|
||||||
ThermionAsset? boundingBoxAsset;
|
ThermionAsset? boundingBoxAsset;
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future dispose() async {
|
||||||
|
_childEntities?.free();
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -326,14 +352,14 @@ class FFIAsset extends ThermionAsset {
|
|||||||
vertices[23] = max[2]; // v7
|
vertices[23] = max[2]; // v7
|
||||||
|
|
||||||
// Indices for lines (24 indices for 12 lines)
|
// Indices for lines (24 indices for 12 lines)
|
||||||
final indices = [
|
final indices = Uint16List.fromList([
|
||||||
// Bottom face
|
// Bottom face
|
||||||
0, 1, 1, 2, 2, 3, 3, 0,
|
0, 1, 1, 2, 2, 3, 3, 0,
|
||||||
// Top face
|
// Top face
|
||||||
4, 5, 5, 6, 6, 7, 7, 4,
|
4, 5, 5, 6, 6, 7, 7, 4,
|
||||||
// Vertical edges
|
// Vertical edges
|
||||||
0, 4, 1, 5, 2, 6, 3, 7
|
0, 4, 1, 5, 2, 6, 3, 7
|
||||||
];
|
]);
|
||||||
|
|
||||||
// Create unlit material instance for the wireframe
|
// Create unlit material instance for the wireframe
|
||||||
final materialInstancePtr =
|
final materialInstancePtr =
|
||||||
@@ -366,6 +392,10 @@ class FFIAsset extends ThermionAsset {
|
|||||||
|
|
||||||
TransformManager_setParent(Engine_getTransformManager(app.engine),
|
TransformManager_setParent(Engine_getTransformManager(app.engine),
|
||||||
boundingBoxAsset!.entity, entity, false);
|
boundingBoxAsset!.entity, entity, false);
|
||||||
|
geometry.uvs?.free();
|
||||||
|
geometry.normals?.free();
|
||||||
|
geometry.vertices.free();
|
||||||
|
geometry.indices.free();
|
||||||
}
|
}
|
||||||
return boundingBoxAsset!;
|
return boundingBoxAsset!;
|
||||||
}
|
}
|
||||||
@@ -461,7 +491,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
if (weights.isEmpty) {
|
if (weights.isEmpty) {
|
||||||
throw Exception("Weights must not be empty");
|
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++) {
|
for (int i = 0; i < weights.length; i++) {
|
||||||
weightsPtr[i] = weights[i];
|
weightsPtr[i] = weights[i];
|
||||||
@@ -470,7 +500,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
AnimationManager_setMorphTargetWeightsRenderThread(
|
AnimationManager_setMorphTargetWeightsRenderThread(
|
||||||
animationManager, entity, weightsPtr, weights.length, cb);
|
animationManager, entity, weightsPtr, weights.length, cb);
|
||||||
});
|
});
|
||||||
allocator.free(weightsPtr);
|
free(weightsPtr);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
@@ -489,13 +519,13 @@ class FFIAsset extends ThermionAsset {
|
|||||||
|
|
||||||
var count = AnimationManager_getMorphTargetNameCount(
|
var count = AnimationManager_getMorphTargetNameCount(
|
||||||
animationManager, asset, entity);
|
animationManager, asset, entity);
|
||||||
var outPtr = allocator<Char>(255);
|
var outPtr = allocate<Char>(255);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
AnimationManager_getMorphTargetName(
|
AnimationManager_getMorphTargetName(
|
||||||
animationManager, asset, entity, outPtr, i);
|
animationManager, asset, entity, outPtr, i);
|
||||||
names.add(outPtr.cast<Utf8>().toDartString());
|
names.add(outPtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
allocator.free(outPtr);
|
free(outPtr);
|
||||||
return names.cast<String>();
|
return names.cast<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,9 +535,9 @@ class FFIAsset extends ThermionAsset {
|
|||||||
Future<List<String>> getBoneNames({int skinIndex = 0}) async {
|
Future<List<String>> getBoneNames({int skinIndex = 0}) async {
|
||||||
var count =
|
var count =
|
||||||
AnimationManager_getBoneCount(animationManager, asset, skinIndex);
|
AnimationManager_getBoneCount(animationManager, asset, skinIndex);
|
||||||
var out = allocator<Pointer<Char>>(count);
|
var out = allocate<PointerClass<Char>>(count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
out[i] = allocator<Char>(255);
|
out[i] = allocate<Char>(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationManager_getBoneNames(animationManager, asset, out, skinIndex);
|
AnimationManager_getBoneNames(animationManager, asset, out, skinIndex);
|
||||||
@@ -516,6 +546,10 @@ class FFIAsset extends ThermionAsset {
|
|||||||
var namePtr = out[i];
|
var namePtr = out[i];
|
||||||
names.add(namePtr.cast<Utf8>().toDartString());
|
names.add(namePtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
free(out[i]);
|
||||||
|
}
|
||||||
|
free(out);
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,12 +561,12 @@ class FFIAsset extends ThermionAsset {
|
|||||||
var animationCount =
|
var animationCount =
|
||||||
AnimationManager_getAnimationCount(animationManager, asset);
|
AnimationManager_getAnimationCount(animationManager, asset);
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
var outPtr = allocator<Char>(255);
|
var outPtr = allocate<Char>(255);
|
||||||
for (int i = 0; i < animationCount; i++) {
|
for (int i = 0; i < animationCount; i++) {
|
||||||
AnimationManager_getAnimationName(animationManager, asset, outPtr, i);
|
AnimationManager_getAnimationName(animationManager, asset, outPtr, i);
|
||||||
names.add(outPtr.cast<Utf8>().toDartString());
|
names.add(outPtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
allocator.free(outPtr);
|
free(outPtr);
|
||||||
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
@@ -636,6 +670,9 @@ class FFIAsset extends ThermionAsset {
|
|||||||
animation.numFrames,
|
animation.numFrames,
|
||||||
animation.frameLengthInMs);
|
animation.frameLengthInMs);
|
||||||
|
|
||||||
|
frameData.data.free();
|
||||||
|
indices.free();
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw Exception("Failed to set morph animation data for ${meshName}");
|
throw Exception("Failed to set morph animation data for ${meshName}");
|
||||||
}
|
}
|
||||||
@@ -659,7 +696,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
throw UnimplementedError("TODO - support skinIndex != 0 ");
|
throw UnimplementedError("TODO - support skinIndex != 0 ");
|
||||||
}
|
}
|
||||||
var boneNames = await getBoneNames();
|
var boneNames = await getBoneNames();
|
||||||
var restLocalTransformsRaw = allocator<Float>(boneNames.length * 16);
|
var restLocalTransformsRaw = allocate<Float>(boneNames.length * 16);
|
||||||
AnimationManager_getRestLocalTransforms(animationManager, asset, skinIndex,
|
AnimationManager_getRestLocalTransforms(animationManager, asset, skinIndex,
|
||||||
restLocalTransformsRaw, boneNames.length);
|
restLocalTransformsRaw, boneNames.length);
|
||||||
|
|
||||||
@@ -671,11 +708,11 @@ class FFIAsset extends ThermionAsset {
|
|||||||
}
|
}
|
||||||
restLocalTransforms.add(Matrix4.fromList(values));
|
restLocalTransforms.add(Matrix4.fromList(values));
|
||||||
}
|
}
|
||||||
allocator.free(restLocalTransformsRaw);
|
free(restLocalTransformsRaw);
|
||||||
|
|
||||||
var numFrames = animation.frameData.length;
|
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(
|
var bones = await Future.wait(List<Future<ThermionEntity>>.generate(
|
||||||
boneNames.length, (i) => getBone(i)));
|
boneNames.length, (i) => getBone(i)));
|
||||||
@@ -720,8 +757,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
baseTransform * (worldInverse * frameTransform * world);
|
baseTransform * (worldInverse * frameTransform * world);
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 16; j++) {
|
for (int j = 0; j < 16; j++) {
|
||||||
data.elementAt((frameNum * 16) + j).value =
|
data[(frameNum * 16) + j] = newLocalTransform.storage[j];
|
||||||
newLocalTransform.storage[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,25 +773,41 @@ class FFIAsset extends ThermionAsset {
|
|||||||
fadeInInSecs,
|
fadeInInSecs,
|
||||||
maxDelta);
|
maxDelta);
|
||||||
}
|
}
|
||||||
allocator.free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<Matrix4> getLocalTransform({ThermionEntity? entity}) async {
|
Future<Matrix4> getLocalTransform({ThermionEntity? entity}) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
entity ??= this.entity;
|
entity ??= this.entity;
|
||||||
return double4x4ToMatrix4(
|
final transform = double4x4ToMatrix4(
|
||||||
TransformManager_getLocalTransform(app.transformManager, entity));
|
TransformManager_getLocalTransform(app.transformManager, entity));
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
}
|
||||||
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<Matrix4> getWorldTransform({ThermionEntity? entity}) async {
|
Future<Matrix4> getWorldTransform({ThermionEntity? entity}) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
entity ??= this.entity;
|
entity ??= this.entity;
|
||||||
return double4x4ToMatrix4(
|
var transform = double4x4ToMatrix4(
|
||||||
TransformManager_getWorldTransform(app.transformManager, entity));
|
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,
|
Future<Matrix4> getInverseBindMatrix(int boneIndex,
|
||||||
{int skinIndex = 0}) async {
|
{int skinIndex = 0}) async {
|
||||||
var matrix = Float32List(16);
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
var matrixIn = Float32List(16);
|
||||||
AnimationManager_getInverseBindMatrix(
|
AnimationManager_getInverseBindMatrix(
|
||||||
animationManager, asset, skinIndex, boneIndex, matrix.address);
|
animationManager, asset, skinIndex, boneIndex, matrixIn.address);
|
||||||
return Matrix4.fromList(matrix);
|
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) {
|
if (skinIndex != 0) {
|
||||||
throw UnimplementedError("TOOD");
|
throw UnimplementedError("TOOD");
|
||||||
}
|
}
|
||||||
final ptr = allocator<Float>(16);
|
final ptr = allocate<Float>(16);
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
ptr[i] = transform.storage[i];
|
ptr[i] = transform.storage[i];
|
||||||
}
|
}
|
||||||
@@ -822,7 +883,7 @@ class FFIAsset extends ThermionAsset {
|
|||||||
animationManager, entity, skinIndex, boneIndex, ptr, cb);
|
animationManager, entity, skinIndex, boneIndex, ptr, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
allocator.free(ptr);
|
free(ptr);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw Exception("Failed to set bone transform");
|
throw Exception("Failed to set bone transform");
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
import 'dart:ffi';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||||
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/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
import '../../../../utils/src/matrix.dart';
|
import '../../../utils/src/matrix.dart';
|
||||||
|
|
||||||
class FFICamera extends Camera {
|
class FFICamera extends Camera {
|
||||||
final Pointer<TCamera> camera;
|
final Pointer<TCamera> camera;
|
||||||
@@ -31,7 +26,15 @@ class FFICamera extends Camera {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<Matrix4> getModelMatrix() async {
|
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
|
@override
|
||||||
Future<Matrix4> getProjectionMatrix() async {
|
Future<Matrix4> getProjectionMatrix() async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
var matrixStruct = Camera_getProjectionMatrix(camera);
|
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
|
@override
|
||||||
Future<Matrix4> getCullingProjectionMatrix() async {
|
Future<Matrix4> getCullingProjectionMatrix() async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
var matrixStruct = Camera_getCullingProjectionMatrix(camera);
|
var matrixStruct = Camera_getCullingProjectionMatrix(camera);
|
||||||
return double4x4ToMatrix4(matrixStruct);
|
final cpMat = double4x4ToMatrix4(matrixStruct);
|
||||||
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
}
|
||||||
|
return cpMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -81,7 +101,15 @@ class FFICamera extends Camera {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setModelMatrix(Matrix4 matrix) async {
|
Future setModelMatrix(Matrix4 matrix) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
stackPtr = stackSave();
|
||||||
|
}
|
||||||
Camera_setModelMatrix(camera, matrix.storage.address);
|
Camera_setModelMatrix(camera, matrix.storage.address);
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
stackRestore(stackPtr);
|
||||||
|
matrix.storage.free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -122,6 +150,10 @@ class FFICamera extends Camera {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<Frustum> getFrustum() async {
|
Future<Frustum> getFrustum() async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
var out = Float64List(24);
|
var out = Float64List(24);
|
||||||
Camera_getFrustum(camera, out.address);
|
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.plane3.setFromComponents(out[12], out[13], out[14], out[15]);
|
||||||
frustum.plane4.setFromComponents(out[16], out[17], out[18], out[19]);
|
frustum.plane4.setFromComponents(out[16], out[17], out[18], out[19]);
|
||||||
frustum.plane5.setFromComponents(out[20], out[21], out[22], out[23]);
|
frustum.plane5.setFromComponents(out[20], out[21], out[22], out[23]);
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
out.free();
|
||||||
|
}
|
||||||
return frustum;
|
return frustum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Matrix4> getViewMatrix() async {
|
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
|
@override
|
||||||
Future setProjection(Projection projection, double left, double right,
|
Future setProjection(Projection projection, double left, double right,
|
||||||
double bottom, double top, double near, double far) async {
|
double bottom, double top, double near, double far) async {
|
||||||
Camera_setProjection(camera, TProjection.values[projection.index], left,
|
Camera_setProjection(
|
||||||
right, bottom, top, near, far);
|
camera, projection.index, left, right, bottom, top, near, far);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future destroy() async {
|
Future destroy() async {
|
||||||
@@ -1,26 +1,23 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_gizmo.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_gizmo.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_material.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_swapchain.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_texture.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_view.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/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
import 'resource_loader.dart';
|
||||||
|
|
||||||
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
||||||
|
|
||||||
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
|
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
|
||||||
FFIFilamentConfig(
|
FFIFilamentConfig(
|
||||||
{required super.resourceLoader,
|
{super.resourceLoader = null,
|
||||||
super.backend = Backend.DEFAULT,
|
super.backend = Backend.DEFAULT,
|
||||||
super.platform = null,
|
super.platform = null,
|
||||||
super.sharedContext = null,
|
super.sharedContext = null,
|
||||||
@@ -38,9 +35,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
final Pointer<TRenderTicker> renderTicker;
|
final Pointer<TRenderTicker> renderTicker;
|
||||||
final Pointer<TNameComponentManager> nameComponentManager;
|
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(
|
FFIFilamentApp(
|
||||||
this.engine,
|
this.engine,
|
||||||
@@ -52,7 +49,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
this.ubershaderMaterialProvider,
|
this.ubershaderMaterialProvider,
|
||||||
this.renderTicker,
|
this.renderTicker,
|
||||||
this.nameComponentManager,
|
this.nameComponentManager,
|
||||||
this.resourceLoader)
|
Future<Uint8List> Function(String uri)? resourceLoader)
|
||||||
: super(
|
: super(
|
||||||
engine: engine,
|
engine: engine,
|
||||||
gltfAssetLoader: gltfAssetLoader,
|
gltfAssetLoader: gltfAssetLoader,
|
||||||
@@ -60,15 +57,13 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
transformManager: transformManager,
|
transformManager: transformManager,
|
||||||
lightManager: lightManager,
|
lightManager: lightManager,
|
||||||
renderableManager: renderableManager,
|
renderableManager: renderableManager,
|
||||||
ubershaderMaterialProvider: ubershaderMaterialProvider) {}
|
ubershaderMaterialProvider: ubershaderMaterialProvider) {
|
||||||
|
this.resourceLoader = resourceLoader ?? defaultResourceLoader;
|
||||||
static Future<Uint8List> _defaultResourceLoader(String path) {
|
|
||||||
print("Loading file $path");
|
|
||||||
return File(path).readAsBytes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future create({FFIFilamentConfig? config}) async {
|
static Future create({FFIFilamentConfig? config}) async {
|
||||||
config ??= FFIFilamentConfig(resourceLoader: _defaultResourceLoader);
|
config ??= FFIFilamentConfig();
|
||||||
|
|
||||||
if (FilamentApp.instance != null) {
|
if (FilamentApp.instance != null) {
|
||||||
await FilamentApp.instance!.destroy();
|
await FilamentApp.instance!.destroy();
|
||||||
}
|
}
|
||||||
@@ -78,7 +73,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
final engine = await withPointerCallback<TEngine>((cb) =>
|
final engine = await withPointerCallback<TEngine>((cb) =>
|
||||||
Engine_createRenderThread(
|
Engine_createRenderThread(
|
||||||
TBackend.values[config!.backend.index].index,
|
config!.backend.value,
|
||||||
config.platform ?? nullptr,
|
config.platform ?? nullptr,
|
||||||
config.sharedContext ?? nullptr,
|
config.sharedContext ?? nullptr,
|
||||||
config.stereoscopicEyeCount,
|
config.stereoscopicEyeCount,
|
||||||
@@ -96,7 +91,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
final lightManager = Engine_getLightManager(engine);
|
final lightManager = Engine_getLightManager(engine);
|
||||||
final renderableManager = Engine_getRenderableManager(engine);
|
final renderableManager = Engine_getRenderableManager(engine);
|
||||||
|
|
||||||
final renderTicker = RenderTicker_create(renderer);
|
final renderTicker = RenderTicker_create(engine, renderer);
|
||||||
|
|
||||||
RenderThread_setRenderTicker(renderTicker);
|
RenderThread_setRenderTicker(renderTicker);
|
||||||
|
|
||||||
@@ -113,18 +108,25 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
renderTicker,
|
renderTicker,
|
||||||
nameComponentManager,
|
nameComponentManager,
|
||||||
config.resourceLoader);
|
config.resourceLoader);
|
||||||
|
_logger.info("Initialization complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
final _swapChains = <FFISwapChain, List<FFIView>>{};
|
final _swapChains = <FFISwapChain, List<FFIView>>{};
|
||||||
final viewsPtr = calloc<Pointer<TView>>(255);
|
late Pointer<PointerClass<TView>> viewsPtr =
|
||||||
|
allocate<PointerClass>(255).cast();
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future updateRenderOrder() async {
|
Future updateRenderOrder() async {
|
||||||
|
_logger.info("updateRenderOrder");
|
||||||
|
if (_swapChains.length == 0) {
|
||||||
|
_logger.warning("No swapchains, ignoring updateRenderOrder");
|
||||||
|
}
|
||||||
for (final swapChain in _swapChains.keys) {
|
for (final swapChain in _swapChains.keys) {
|
||||||
final views = _swapChains[swapChain];
|
final views = _swapChains[swapChain];
|
||||||
if (views == null) {
|
if (views == null) {
|
||||||
|
_logger.info("No views found for swapchain $swapChain");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +139,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
RenderTicker_setRenderable(
|
RenderTicker_setRenderable(
|
||||||
renderTicker, swapChain.swapChain, viewsPtr, numRenderable);
|
renderTicker, swapChain.swapChain, viewsPtr, numRenderable);
|
||||||
|
_logger.info("Updated render order, $numRenderable renderable views");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +230,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
RenderThread_destroy();
|
RenderThread_destroy();
|
||||||
RenderTicker_destroy(renderTicker);
|
RenderTicker_destroy(renderTicker);
|
||||||
|
|
||||||
calloc.free(viewsPtr);
|
free(viewsPtr);
|
||||||
FilamentApp.instance = null;
|
FilamentApp.instance = null;
|
||||||
for (final callback in _onDestroy) {
|
for (final callback in _onDestroy) {
|
||||||
await callback.call();
|
await callback.call();
|
||||||
@@ -242,6 +245,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
Future destroyAsset(covariant FFIAsset asset) async {
|
Future destroyAsset(covariant FFIAsset asset) async {
|
||||||
await withVoidCallback(
|
await withVoidCallback(
|
||||||
(cb) => SceneAsset_destroyRenderThread(asset.asset, cb));
|
(cb) => SceneAsset_destroyRenderThread(asset.asset, cb));
|
||||||
|
await asset.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -298,8 +302,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
levels,
|
levels,
|
||||||
bitmask,
|
bitmask,
|
||||||
importedTextureHandle ?? 0,
|
importedTextureHandle ?? 0,
|
||||||
TTextureSamplerType.values[textureSamplerType.index],
|
textureSamplerType.index,
|
||||||
TTextureFormat.values[textureFormat.index],
|
textureFormat.index,
|
||||||
cb);
|
cb);
|
||||||
});
|
});
|
||||||
if (texturePtr == nullptr) {
|
if (texturePtr == nullptr) {
|
||||||
@@ -324,24 +328,17 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
TextureCompareMode compareMode = TextureCompareMode.NONE,
|
TextureCompareMode compareMode = TextureCompareMode.NONE,
|
||||||
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
|
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
|
||||||
final samplerPtr = TextureSampler_create();
|
final samplerPtr = TextureSampler_create();
|
||||||
TextureSampler_setMinFilter(
|
TextureSampler_setMinFilter(samplerPtr, minFilter.index);
|
||||||
samplerPtr, TSamplerMinFilter.values[minFilter.index]);
|
TextureSampler_setMagFilter(samplerPtr, magFilter.index);
|
||||||
TextureSampler_setMagFilter(
|
TextureSampler_setWrapModeS(samplerPtr, wrapS.index);
|
||||||
samplerPtr, TSamplerMagFilter.values[magFilter.index]);
|
TextureSampler_setWrapModeT(samplerPtr, wrapT.index);
|
||||||
TextureSampler_setWrapModeS(
|
TextureSampler_setWrapModeR(samplerPtr, wrapR.index);
|
||||||
samplerPtr, TSamplerWrapMode.values[wrapS.index]);
|
|
||||||
TextureSampler_setWrapModeT(
|
|
||||||
samplerPtr, TSamplerWrapMode.values[wrapT.index]);
|
|
||||||
TextureSampler_setWrapModeR(
|
|
||||||
samplerPtr, TSamplerWrapMode.values[wrapR.index]);
|
|
||||||
if (anisotropy > 0) {
|
if (anisotropy > 0) {
|
||||||
TextureSampler_setAnisotropy(samplerPtr, anisotropy);
|
TextureSampler_setAnisotropy(samplerPtr, anisotropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureSampler_setCompareMode(
|
TextureSampler_setCompareMode(
|
||||||
samplerPtr,
|
samplerPtr, compareMode.index, compareFunc.index);
|
||||||
TSamplerCompareMode.values[compareMode.index],
|
|
||||||
TSamplerCompareFunc.values[compareFunc.index]);
|
|
||||||
|
|
||||||
return FFITextureSampler(samplerPtr);
|
return FFITextureSampler(samplerPtr);
|
||||||
}
|
}
|
||||||
@@ -351,11 +348,20 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
///
|
///
|
||||||
Future<LinearImage> decodeImage(Uint8List data) async {
|
Future<LinearImage> decodeImage(Uint8List data) async {
|
||||||
final name = "image";
|
final name = "image";
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
var ptr = Image_decode(
|
var ptr = Image_decode(
|
||||||
data.address,
|
data.address,
|
||||||
data.length,
|
data.length,
|
||||||
name.toNativeUtf8().cast<Char>(),
|
name.toNativeUtf8().cast<Char>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
data.free();
|
||||||
|
}
|
||||||
if (ptr == nullptr) {
|
if (ptr == nullptr) {
|
||||||
throw Exception("Failed to decode image");
|
throw Exception("Failed to decode image");
|
||||||
}
|
}
|
||||||
@@ -374,9 +380,17 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<Material> createMaterial(Uint8List data) async {
|
Future<Material> createMaterial(Uint8List data) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
var ptr = await withPointerCallback<TMaterial>((cb) {
|
var ptr = await withPointerCallback<TMaterial>((cb) {
|
||||||
Engine_buildMaterialRenderThread(engine, data.address, data.length, cb);
|
Engine_buildMaterialRenderThread(engine, data.address, data.length, cb);
|
||||||
});
|
});
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
data.free();
|
||||||
|
}
|
||||||
return FFIMaterial(ptr, this);
|
return FFIMaterial(ptr, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,6 +434,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
bool hasSheen = false,
|
bool hasSheen = false,
|
||||||
bool hasIOR = false,
|
bool hasIOR = false,
|
||||||
bool hasVolume = false}) async {
|
bool hasVolume = false}) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
|
||||||
final key = Struct.create<TMaterialKey>();
|
final key = Struct.create<TMaterialKey>();
|
||||||
|
|
||||||
key.doubleSided = doubleSided;
|
key.doubleSided = doubleSided;
|
||||||
@@ -464,6 +483,10 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
MaterialProvider_createMaterialInstanceRenderThread(
|
MaterialProvider_createMaterialInstanceRenderThread(
|
||||||
ubershaderMaterialProvider, key.address, cb);
|
ubershaderMaterialProvider, key.address, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
}
|
||||||
if (materialInstance == nullptr) {
|
if (materialInstance == nullptr) {
|
||||||
throw Exception("Failed to create material instance");
|
throw Exception("Failed to create material instance");
|
||||||
}
|
}
|
||||||
@@ -506,7 +529,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
final swapchain = _swapChains.keys.first;
|
final swapchain = _swapChains.keys.first;
|
||||||
final view = _swapChains[swapchain]!.first;
|
final view = _swapChains[swapchain]!.first;
|
||||||
await withBoolCallback((cb) {
|
await withBoolCallback((cb) {
|
||||||
Renderer_beginFrameRenderThread(renderer, swapchain.swapChain, 0, cb);
|
Renderer_beginFrameRenderThread(
|
||||||
|
renderer, swapchain.swapChain, 0.toBigInt, cb);
|
||||||
});
|
});
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Renderer_renderRenderThread(
|
Renderer_renderRenderThread(
|
||||||
@@ -515,10 +539,16 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
cb,
|
cb,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Renderer_endFrameRenderThread(renderer, 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) {
|
for (final hook in _hooks) {
|
||||||
await hook.call();
|
await hook.call();
|
||||||
}
|
}
|
||||||
final completer = Completer();
|
|
||||||
|
|
||||||
final callback = NativeCallable<Void Function()>.listener(() {
|
RenderThread_requestFrameAsync();
|
||||||
completer.complete(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
RenderThread_requestFrame(callback.nativeFunction.cast());
|
|
||||||
|
|
||||||
try {
|
|
||||||
await completer.future.timeout(Duration(seconds: 1));
|
|
||||||
} catch (err) {
|
|
||||||
print("WARNING - render call timed out");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -669,7 +688,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
PixelDataFormat pixelDataFormat = PixelDataFormat.RGBA,
|
PixelDataFormat pixelDataFormat = PixelDataFormat.RGBA,
|
||||||
PixelDataType pixelDataType = PixelDataType.FLOAT,
|
PixelDataType pixelDataType = PixelDataType.FLOAT,
|
||||||
Future Function(View)? beforeRender}) async {
|
Future Function(View)? beforeRender}) async {
|
||||||
|
|
||||||
if (swapChain == null) {
|
if (swapChain == null) {
|
||||||
if (_swapChains.isEmpty) {
|
if (_swapChains.isEmpty) {
|
||||||
throw Exception("No swapchains registered");
|
throw Exception("No swapchains registered");
|
||||||
@@ -683,7 +701,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
await updateRenderOrder();
|
await updateRenderOrder();
|
||||||
|
|
||||||
await withBoolCallback((cb) {
|
await withBoolCallback((cb) {
|
||||||
Renderer_beginFrameRenderThread(renderer, swapChain!.swapChain, 0, cb);
|
Renderer_beginFrameRenderThread(
|
||||||
|
renderer, swapChain!.swapChain, 0.toBigInt, cb);
|
||||||
});
|
});
|
||||||
final views = <FFIView>[];
|
final views = <FFIView>[];
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
@@ -720,6 +739,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
: view.renderTarget!.renderTarget,
|
: view.renderTarget!.renderTarget,
|
||||||
// TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
// TPixelDataFormat.PIXELDATAFORMAT_RGBA,
|
||||||
// TPixelDataType.PIXELDATATYPE_UBYTE,
|
// TPixelDataType.PIXELDATATYPE_UBYTE,
|
||||||
|
// TPixelDataFormat.fromValue(pixelDataFormat.value),
|
||||||
|
// TPixelDataType.fromValue(pixelDataType.value),
|
||||||
pixelDataFormat.value,
|
pixelDataFormat.value,
|
||||||
pixelDataType.value,
|
pixelDataType.value,
|
||||||
pixelBuffer.address,
|
pixelBuffer.address,
|
||||||
@@ -734,7 +755,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await withVoidCallback((cb) {
|
await withVoidCallback((cb) {
|
||||||
Engine_flushAndWaitRenderThead(engine, cb);
|
if (FILAMENT_SINGLE_THREADED) {
|
||||||
|
Engine_executeRenderThread(engine, cb);
|
||||||
|
} else {
|
||||||
|
Engine_flushAndWaitRenderThread(engine, cb);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return pixelBuffers;
|
return pixelBuffers;
|
||||||
}
|
}
|
||||||
@@ -759,70 +784,96 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
int layer = 0,
|
int layer = 0,
|
||||||
String? relativeResourcePath,
|
String? relativeResourcePath,
|
||||||
bool loadResourcesAsync = false}) async {
|
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>[];
|
final resources = <FinalizableUint8List>[];
|
||||||
|
try {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < resourceUriCount; i++) {
|
loadResourcesAsync = FILAMENT_SINGLE_THREADED;
|
||||||
final resourceUriDart = resourceUris[i].cast<Utf8>().toDartString();
|
|
||||||
final resourceData = await resourceLoader(relativeResourcePath == null
|
|
||||||
? resourceUriDart
|
|
||||||
: "$relativeResourcePath/$resourceUriDart");
|
|
||||||
|
|
||||||
resources.add(FinalizableUint8List(resourceUris[i], resourceData));
|
if (relativeResourcePath != null && !relativeResourcePath.endsWith("/")) {
|
||||||
|
relativeResourcePath = "$relativeResourcePath/";
|
||||||
await withVoidCallback((cb) =>
|
}
|
||||||
GltfResourceLoader_addResourceDataRenderThread(
|
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||||
gltfResourceLoader,
|
(cb) => GltfResourceLoader_createRenderThread(
|
||||||
resourceUris[i],
|
engine,
|
||||||
resourceData.address,
|
relativeResourcePath?.toNativeUtf8().cast<Char>() ?? nullptr,
|
||||||
resourceData.lengthInBytes,
|
|
||||||
cb));
|
cb));
|
||||||
}
|
|
||||||
if (loadResourcesAsync) {
|
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
||||||
final result = await withBoolCallback((cb) => GltfResourceLoader_asyncBeginLoadRenderThread(gltfResourceLoader, filamentAsset, cb));
|
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader,
|
||||||
if(!result) {
|
data.address, data.length, numInstances, cb));
|
||||||
throw Exception("Failed to begin async loading");
|
|
||||||
|
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);
|
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) =>
|
final asset = await withPointerCallback<TSceneAsset>((cb) =>
|
||||||
GltfResourceLoader_loadResourcesRenderThread(
|
SceneAsset_createFromFilamentAssetRenderThread(engine,
|
||||||
gltfResourceLoader, filamentAsset, cb));
|
gltfAssetLoader, nameComponentManager, filamentAsset, cb));
|
||||||
if (!result) {
|
|
||||||
throw Exception("Failed to load resources");
|
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 {
|
Future destroyView(covariant FFIView view) async {
|
||||||
@@ -833,12 +884,13 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
await withVoidCallback(
|
await withVoidCallback(
|
||||||
(cb) => Engine_destroyViewRenderThread(engine, view.view, cb));
|
(cb) => Engine_destroyViewRenderThread(engine, view.view, cb));
|
||||||
for(final swapchain in _swapChains.keys) {
|
for (final swapchain in _swapChains.keys) {
|
||||||
if(_swapChains[swapchain]!.contains(view)) {
|
if (_swapChains[swapchain]!.contains(view)) {
|
||||||
_swapChains[swapchain]!.remove(view);
|
_swapChains[swapchain]!.remove(view);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await view.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future destroyScene(covariant FFIScene scene) async {
|
Future destroyScene(covariant FFIScene scene) async {
|
||||||
@@ -847,9 +899,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Pointer<TColorGrading>> createColorGrading(ToneMapper mapper) async {
|
Future<Pointer<TColorGrading>> createColorGrading(ToneMapper mapper) async {
|
||||||
return withPointerCallback<TColorGrading>((cb) =>
|
return withPointerCallback<TColorGrading>(
|
||||||
ColorGrading_createRenderThread(
|
(cb) => ColorGrading_createRenderThread(engine, mapper.index, cb));
|
||||||
engine, TToneMapping.values[mapper.index], cb));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FFIMaterial? _gizmoMaterial;
|
FFIMaterial? _gizmoMaterial;
|
||||||
@@ -859,6 +910,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
///
|
///
|
||||||
Future<GizmoAsset> createGizmo(covariant FFIView view,
|
Future<GizmoAsset> createGizmo(covariant FFIView view,
|
||||||
Pointer animationManager, GizmoType gizmoType) async {
|
Pointer animationManager, GizmoType gizmoType) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
|
||||||
if (_gizmoMaterial == null) {
|
if (_gizmoMaterial == null) {
|
||||||
final materialPtr = await withPointerCallback<TMaterial>((cb) {
|
final materialPtr = await withPointerCallback<TMaterial>((cb) {
|
||||||
Material_createGizmoMaterialRenderThread(engine, cb);
|
Material_createGizmoMaterialRenderThread(engine, cb);
|
||||||
@@ -867,7 +923,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||||
(cb) => GltfResourceLoader_createRenderThread(engine, nullptr, cb));
|
(cb) =>
|
||||||
|
GltfResourceLoader_createRenderThread(engine, nullptr.cast(), cb));
|
||||||
|
|
||||||
final gizmo = await withPointerCallback<TGizmo>((cb) {
|
final gizmo = await withPointerCallback<TGizmo>((cb) {
|
||||||
Gizmo_createRenderThread(
|
Gizmo_createRenderThread(
|
||||||
@@ -877,7 +934,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
nameComponentManager,
|
nameComponentManager,
|
||||||
view.view,
|
view.view,
|
||||||
_gizmoMaterial!.pointer,
|
_gizmoMaterial!.pointer,
|
||||||
TGizmoType.values[gizmoType.index],
|
gizmoType.index,
|
||||||
cb);
|
cb);
|
||||||
});
|
});
|
||||||
if (gizmo == nullptr) {
|
if (gizmo == nullptr) {
|
||||||
@@ -889,11 +946,17 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
SceneAsset_getChildEntities(
|
SceneAsset_getChildEntities(
|
||||||
gizmo.cast<TSceneAsset>(), gizmoEntities.address);
|
gizmo.cast<TSceneAsset>(), gizmoEntities.address);
|
||||||
|
|
||||||
return FFIGizmo(gizmo.cast<TSceneAsset>(), this,
|
final gizmoAsset = FFIGizmo(gizmo.cast<TSceneAsset>(), this,
|
||||||
animationManager.cast<TAnimationManager>(),
|
animationManager.cast<TAnimationManager>(),
|
||||||
view: view,
|
view: view,
|
||||||
entities: gizmoEntities.toSet()
|
entities: gizmoEntities.toSet()
|
||||||
..add(SceneAsset_getEntity(gizmo.cast<TSceneAsset>())));
|
..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,
|
{List<MaterialInstance>? materialInstances,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
bool addToScene = true}) async {
|
bool addToScene = true}) async {
|
||||||
var assetPtr = await withPointerCallback<TSceneAsset>((callback) {
|
late Pointer stackPtr;
|
||||||
var ptrList = Int64List(materialInstances?.length ?? 0);
|
if (FILAMENT_WASM) {
|
||||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
//stackPtr = stackSave();
|
||||||
ptrList.setRange(
|
}
|
||||||
0,
|
|
||||||
materialInstances.length,
|
|
||||||
materialInstances
|
|
||||||
.cast<FFIMaterialInstance>()
|
|
||||||
.map((mi) => mi.pointer.address)
|
|
||||||
.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
engine,
|
||||||
geometry.vertices.address,
|
geometry.vertices.address,
|
||||||
geometry.vertices.length,
|
geometry.vertices.length,
|
||||||
@@ -928,10 +996,20 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
geometry.indices.address,
|
geometry.indices.address,
|
||||||
geometry.indices.length,
|
geometry.indices.length,
|
||||||
geometry.primitiveType.index,
|
geometry.primitiveType.index,
|
||||||
ptrList.address.cast<Pointer<TMaterialInstance>>(),
|
ptrList.address.cast(),
|
||||||
ptrList.length,
|
ptrList.length ?? 0,
|
||||||
callback);
|
callback);
|
||||||
|
return ptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
ptrList?.free();
|
||||||
|
geometry.vertices.free();
|
||||||
|
geometry.normals?.free();
|
||||||
|
geometry.uvs?.free();
|
||||||
|
}
|
||||||
|
|
||||||
if (assetPtr == nullptr) {
|
if (assetPtr == nullptr) {
|
||||||
throw Exception("Failed to create geometry");
|
throw Exception("Failed to create geometry");
|
||||||
}
|
}
|
||||||
@@ -943,11 +1021,16 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future flush() async {
|
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()>[];
|
final _onDestroy = <Future Function()>[];
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -955,10 +1038,3 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
_onDestroy.add(callback);
|
_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 'dart:async';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
import 'ffi_view.dart';
|
import 'ffi_view.dart';
|
||||||
|
|
||||||
class FFIGizmo extends FFIAsset implements GizmoAsset {
|
class FFIGizmo extends FFIAsset implements GizmoAsset {
|
||||||
final Set<ThermionEntity> entities;
|
final Set<ThermionEntity> entities;
|
||||||
late NativeCallable<GizmoPickCallbackFunction> _nativeCallback;
|
|
||||||
|
late final CallbackHolder<GizmoPickCallbackFunction> _callbackHolder;
|
||||||
|
|
||||||
void Function(GizmoPickResultType axis, Vector3 coords)? _callback;
|
void Function(GizmoPickResultType axis, Vector3 coords)? _callback;
|
||||||
|
|
||||||
late FFIView view;
|
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(
|
FFIGizmo(
|
||||||
super.asset,
|
super.asset,
|
||||||
super.app,
|
super.app,
|
||||||
@@ -32,10 +22,38 @@ class FFIGizmo extends FFIAsset implements GizmoAsset {
|
|||||||
required this.view,
|
required this.view,
|
||||||
required this.entities,
|
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
|
@override
|
||||||
Future removeStencilHighlight() async {
|
Future removeStencilHighlight() async {
|
||||||
throw Exception("Not supported for gizmo");
|
throw Exception("Not supported for gizmo");
|
||||||
@@ -58,13 +76,18 @@ class FFIGizmo extends FFIAsset implements GizmoAsset {
|
|||||||
final viewport = await view.getViewport();
|
final viewport = await view.getViewport();
|
||||||
y = viewport.height - y;
|
y = viewport.height - y;
|
||||||
|
|
||||||
Gizmo_pick(asset.cast<TGizmo>(), x, y, _nativeCallback.nativeFunction);
|
Gizmo_pick(asset.cast<TGizmo>(), x, y, _callbackHolder.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future highlight(Axis axis) async {
|
Future highlight(Axis axis) async {
|
||||||
Gizmo_unhighlight(asset.cast<TGizmo>());
|
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
|
@override
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
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/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/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class FFIMaterial extends Material {
|
class FFIMaterial extends Material {
|
||||||
@@ -73,7 +70,11 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setParameterFloat3Array(String name, List<Vector3> array) async {
|
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);
|
final data = Float64List(array.length * 3);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (final item in array) {
|
for (final item in array) {
|
||||||
@@ -84,7 +85,11 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
}
|
}
|
||||||
MaterialInstance_setParameterFloat3Array(
|
MaterialInstance_setParameterFloat3Array(
|
||||||
pointer, ptr, data.address, array.length * 3);
|
pointer, ptr, data.address, array.length * 3);
|
||||||
calloc.free(ptr);
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
data.free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -102,45 +107,38 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setDepthFunc(SamplerCompareFunction depthFunc) async {
|
Future setDepthFunc(SamplerCompareFunction depthFunc) async {
|
||||||
MaterialInstance_setDepthFunc(
|
MaterialInstance_setDepthFunc(pointer, depthFunc.index);
|
||||||
pointer, TSamplerCompareFunc.values[depthFunc.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setStencilCompareFunction(SamplerCompareFunction func,
|
Future setStencilCompareFunction(SamplerCompareFunction func,
|
||||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||||
MaterialInstance_setStencilCompareFunction(
|
MaterialInstance_setStencilCompareFunction(pointer, func.index, face.index);
|
||||||
pointer,
|
|
||||||
TSamplerCompareFunc.values[func.index],
|
|
||||||
TStencilFace.values[face.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setStencilOpDepthFail(StencilOperation op,
|
Future setStencilOpDepthFail(StencilOperation op,
|
||||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||||
MaterialInstance_setStencilOpDepthFail(pointer,
|
MaterialInstance_setStencilOpDepthFail(pointer, op.index, face.index);
|
||||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setStencilOpDepthStencilPass(StencilOperation op,
|
Future setStencilOpDepthStencilPass(StencilOperation op,
|
||||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||||
MaterialInstance_setStencilOpDepthStencilPass(pointer,
|
MaterialInstance_setStencilOpDepthStencilPass(
|
||||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
pointer, op.index, face.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setStencilOpStencilFail(StencilOperation op,
|
Future setStencilOpStencilFail(StencilOperation op,
|
||||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||||
MaterialInstance_setStencilOpStencilFail(pointer,
|
MaterialInstance_setStencilOpStencilFail(pointer, op.index, face.index);
|
||||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setStencilReferenceValue(int value,
|
Future setStencilReferenceValue(int value,
|
||||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||||
MaterialInstance_setStencilReferenceValue(
|
MaterialInstance_setStencilReferenceValue(pointer, value, face.index);
|
||||||
pointer, value, TStencilFace.values[face.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -150,8 +148,8 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setCullingMode(CullingMode cullingMode) async {
|
Future setCullingMode(CullingMode cullingMode) async {
|
||||||
MaterialInstance_setCullingMode(
|
MaterialInstance_setCullingMode(pointer, cullingMode.index);
|
||||||
pointer, TCullingMode.values[cullingMode.index]);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -177,8 +175,7 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setTransparencyMode(TransparencyMode mode) async {
|
Future setTransparencyMode(TransparencyMode mode) async {
|
||||||
MaterialInstance_setTransparencyMode(
|
MaterialInstance_setTransparencyMode(pointer, mode.index);
|
||||||
pointer, TTransparencyMode.values[mode.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -196,13 +193,7 @@ class FFIMaterialInstance extends MaterialInstance {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setParameterMat4(String name, Matrix4 matrix) async {
|
Future setParameterMat4(String name, Matrix4 matrix) async {
|
||||||
final completer = Completer();
|
MaterialInstance_setParameterMat4(
|
||||||
final func = () {
|
pointer, name.toNativeUtf8().cast<Char>(), matrix.storage.address);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/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_texture.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class FFIRenderTarget extends RenderTarget {
|
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/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||||
import 'callbacks.dart';
|
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||||
|
|
||||||
class FFIScene extends Scene {
|
class FFIScene extends Scene {
|
||||||
final Pointer<TScene> 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';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class FFISwapChain extends SwapChain {
|
class FFISwapChain extends SwapChain {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'dart:typed_data';
|
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';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class FFITexture extends Texture {
|
class FFITexture extends Texture {
|
||||||
@@ -11,13 +11,15 @@ class FFITexture extends Texture {
|
|||||||
|
|
||||||
Future<void> setLinearImage(covariant FFILinearImage image,
|
Future<void> setLinearImage(covariant FFILinearImage image,
|
||||||
PixelDataFormat format, PixelDataType type) async {
|
PixelDataFormat format, PixelDataType type) async {
|
||||||
|
final tPixelDataFormat = format.value;
|
||||||
|
final tPixelDataType = type.value;
|
||||||
final result = await withBoolCallback((cb) {
|
final result = await withBoolCallback((cb) {
|
||||||
Texture_loadImageRenderThread(
|
Texture_loadImageRenderThread(
|
||||||
_engine,
|
_engine,
|
||||||
pointer,
|
pointer,
|
||||||
image.pointer,
|
image.pointer,
|
||||||
format.index,
|
tPixelDataFormat,
|
||||||
type.index,
|
tPixelDataType,
|
||||||
cb);
|
cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -114,28 +116,29 @@ class FFITexture extends Texture {
|
|||||||
Uint8List buffer,
|
Uint8List buffer,
|
||||||
PixelDataFormat format,
|
PixelDataFormat format,
|
||||||
PixelDataType type) async {
|
PixelDataType type) async {
|
||||||
final success = await withBoolCallback((cb) {
|
throw UnimplementedError();
|
||||||
Texture_setImageWithDepthRenderThread(
|
// final success = await withBoolCallback((cb) {
|
||||||
_engine,
|
// Texture_setImageWithDepthRenderThread(
|
||||||
pointer,
|
// _engine,
|
||||||
level,
|
// pointer,
|
||||||
buffer.address,
|
// level,
|
||||||
buffer.lengthInBytes,
|
// buffer.address,
|
||||||
0,
|
// buffer.lengthInBytes,
|
||||||
0,
|
// 0,
|
||||||
zOffset,
|
// 0,
|
||||||
width,
|
// zOffset,
|
||||||
height,
|
// width,
|
||||||
channels,
|
// height,
|
||||||
depth,
|
// channels,
|
||||||
format.index,
|
// depth,
|
||||||
type.index,
|
// format.index,
|
||||||
cb);
|
// type.index,
|
||||||
});
|
// cb);
|
||||||
|
// });
|
||||||
|
|
||||||
if (!success) {
|
// if (!success) {
|
||||||
throw Exception("Failed to set image");
|
// throw Exception("Failed to set image");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -171,16 +174,12 @@ class FFILinearImage extends LinearImage {
|
|||||||
[String name = "image"]) async {
|
[String name = "image"]) async {
|
||||||
final namePtr = name.toNativeUtf8();
|
final namePtr = name.toNativeUtf8();
|
||||||
|
|
||||||
try {
|
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
|
||||||
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
|
Image_decodeRenderThread(
|
||||||
Image_decodeRenderThread(
|
data.address, data.lengthInBytes, namePtr.cast(), cb);
|
||||||
data.address, data.lengthInBytes, namePtr.cast(), cb);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return FFILinearImage(imagePtr);
|
return FFILinearImage(imagePtr);
|
||||||
} finally {
|
|
||||||
calloc.free(namePtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> destroy() async {
|
Future<void> destroy() async {
|
||||||
@@ -2,12 +2,12 @@ import 'dart:async';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'callbacks.dart';
|
|
||||||
import 'ffi_camera.dart';
|
import 'ffi_camera.dart';
|
||||||
|
|
||||||
class FFIView extends View {
|
class FFIView extends View {
|
||||||
@@ -24,14 +24,24 @@ class FFIView extends View {
|
|||||||
|
|
||||||
FFIRenderTarget? renderTarget;
|
FFIRenderTarget? renderTarget;
|
||||||
|
|
||||||
|
late CallbackHolder<PickCallbackFunction> _onPickResultHolder;
|
||||||
|
|
||||||
|
|
||||||
FFIView(this.view, this.app) {
|
FFIView(this.view, this.app) {
|
||||||
final renderTargetPtr = View_getRenderTarget(view);
|
final renderTargetPtr = View_getRenderTarget(view);
|
||||||
if (renderTargetPtr != nullptr) {
|
if (renderTargetPtr != nullptr) {
|
||||||
renderTarget = FFIRenderTarget(renderTargetPtr, app);
|
renderTarget = FFIRenderTarget(renderTargetPtr, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPickResultCallable =
|
_onPickResultHolder =
|
||||||
NativeCallable<PickCallbackFunction>.listener(_onPickResult);
|
_onPickResult.asCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future dispose() async {
|
||||||
|
_onPickResultHolder.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -76,7 +86,7 @@ class FFIView extends View {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Viewport> getViewport() async {
|
Future<Viewport> getViewport() async {
|
||||||
TViewport vp = View_getViewport(view);
|
final vp = View_getViewport(view);
|
||||||
return Viewport(vp.left, vp.bottom, vp.width, vp.height);
|
return Viewport(vp.left, vp.bottom, vp.width, vp.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +151,7 @@ class FFIView extends View {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setRenderQuality(QualityLevel quality) async {
|
Future setRenderQuality(QualityLevel quality) async {
|
||||||
View_setRenderQuality(view, TQualityLevel.values[quality.index]);
|
View_setRenderQuality(view, quality.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future setScene(covariant FFIScene scene) async {
|
Future setScene(covariant FFIScene scene) async {
|
||||||
@@ -154,7 +164,7 @@ class FFIView extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future setBlendMode(BlendMode blendMode) async {
|
Future setBlendMode(BlendMode blendMode) async {
|
||||||
View_setBlendMode(view, TBlendMode.values[blendMode.index]);
|
View_setBlendMode(view, blendMode.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -168,7 +178,6 @@ class FFIView extends View {
|
|||||||
static int kMaxPickRequests = 1024;
|
static int kMaxPickRequests = 1024;
|
||||||
final _pickRequests = List<({void Function(PickResult) handler, int x, int y})?>.generate(kMaxPickRequests, (idx) => null);
|
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;
|
y = viewport.height - y;
|
||||||
|
|
||||||
View_pick(
|
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/bindings/bindings.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||||
|
|
||||||
class GridOverlay extends FFIAsset {
|
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;
|
library;
|
||||||
|
|
||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
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';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
export 'geometry.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';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
enum Projection { Perspective, Orthographic }
|
enum Projection { Perspective, Orthographic }
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
import 'dart:typed_data';
|
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||||
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/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class FilamentConfig<T, U> {
|
class FilamentConfig<T, U> {
|
||||||
final Backend backend;
|
final Backend backend;
|
||||||
final T? renderCallback;
|
final T? renderCallback;
|
||||||
final U? renderCallbackOwner;
|
final U? renderCallbackOwner;
|
||||||
final Future<Uint8List> Function(String) resourceLoader;
|
Future<Uint8List> Function(String)? resourceLoader;
|
||||||
final U? platform;
|
final U? platform;
|
||||||
final U? sharedContext;
|
final U? sharedContext;
|
||||||
final String? uberArchivePath;
|
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();
|
Future unhighlight();
|
||||||
bool isNonPickable(ThermionEntity entity);
|
bool isNonPickable(ThermionEntity entity);
|
||||||
bool isGizmoEntity(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:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.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).
|
/// 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
|
/// [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/interface/layers.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/scene.dart';
|
import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
enum BlendMode {
|
enum BlendMode {
|
||||||
@@ -57,7 +57,10 @@ abstract class View {
|
|||||||
Future pick(int x, int y, void Function(PickResult) resultHandler);
|
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 camera = await view.getCamera();
|
||||||
|
|
||||||
final viewport = await view.getViewport();
|
|
||||||
|
|
||||||
var viewMatrix = await camera.getViewMatrix();
|
|
||||||
var modelMatrix = await camera.getModelMatrix();
|
var modelMatrix = await camera.getModelMatrix();
|
||||||
var projectionMatrix = await camera.getProjectionMatrix();
|
|
||||||
var inverseProjectionMatrix = projectionMatrix.clone()..invert();
|
|
||||||
Vector3 currentPosition = modelMatrix.getTranslation();
|
Vector3 currentPosition = modelMatrix.getTranslation();
|
||||||
|
|
||||||
Vector3 forward = modelMatrix.forward;
|
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:math' ;
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import '../../../thermion_dart.dart';
|
import '../../../thermion_dart.dart';
|
||||||
|
|
||||||
class GeometryHelper {
|
class GeometryHelper {
|
||||||
static Geometry fullscreenQuad() {
|
static Geometry fullscreenQuad() {
|
||||||
final vertices =
|
final vertices = Float32List.fromList([-1.0, -1.0, 1.0, 3.0, -1.0, 1.0, -1.0, 3.0, 1.0]);
|
||||||
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]);
|
||||||
final indices = [0, 1, 2];
|
|
||||||
return Geometry(vertices, indices);
|
return Geometry(vertices, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +54,7 @@ class GeometryHelper {
|
|||||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : 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(
|
static Geometry cube(
|
||||||
@@ -236,7 +234,7 @@ class GeometryHelper {
|
|||||||
20, 21, 22, 20, 22, 23 // 4,0,3,4,3,7
|
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)
|
// 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? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : 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(
|
static Geometry conic(
|
||||||
@@ -440,7 +438,7 @@ class GeometryHelper {
|
|||||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : 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(
|
static Geometry plane(
|
||||||
@@ -493,14 +491,14 @@ class GeometryHelper {
|
|||||||
])
|
])
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
List<int> indices = [
|
final indices = Uint16List.fromList([
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
0,
|
0,
|
||||||
2,
|
2,
|
||||||
3,
|
3,
|
||||||
];
|
]);
|
||||||
|
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
}
|
}
|
||||||
@@ -640,7 +638,7 @@ class GeometryHelper {
|
|||||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : 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);
|
normals: _normals, uvs: _uvs, primitiveType: PrimitiveType.LINES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,7 +792,7 @@ class GeometryHelper {
|
|||||||
])
|
])
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
final indices = [
|
final indices = Uint16List.fromList([
|
||||||
// Front face
|
// Front face
|
||||||
0, 1, 2, 0, 2, 3,
|
0, 1, 2, 0, 2, 3,
|
||||||
// Back face
|
// Back face
|
||||||
@@ -807,7 +805,7 @@ class GeometryHelper {
|
|||||||
16, 17, 18, 16, 18, 19,
|
16, 17, 18, 16, 18, 19,
|
||||||
// Left face
|
// Left face
|
||||||
20, 21, 22, 20, 22, 23
|
20, 21, 22, 20, 22, 23
|
||||||
];
|
]);
|
||||||
|
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
}
|
}
|
||||||
@@ -865,7 +863,7 @@ class GeometryHelper {
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
// Define indices for triangular faces
|
// Define indices for triangular faces
|
||||||
List<int> indices = [
|
Uint16List indices = Uint16List.fromList([
|
||||||
// Bottom face (rectangle)
|
// Bottom face (rectangle)
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
0, 2, 3,
|
0, 2, 3,
|
||||||
@@ -883,7 +881,7 @@ class GeometryHelper {
|
|||||||
// Back rectangular face
|
// Back rectangular face
|
||||||
2, 3, 4,
|
2, 3, 4,
|
||||||
2, 4, 5,
|
2, 4, 5,
|
||||||
];
|
]);
|
||||||
|
|
||||||
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
return Geometry(vertices, indices, normals: _normals, uvs: _uvs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
Future<Uint8List> pixelBufferToBmp(Uint8List pixelBuffer, int width, int height,
|
Future<Uint8List> pixelBufferToBmp(Uint8List pixelBuffer, int width, int height,
|
||||||
{bool hasAlpha = true, bool isFloat = false}) async {
|
{bool hasAlpha = true, bool isFloat = false}) async {
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
// Helper function to convert double4x4 to Matrix4
|
import 'package:thermion_dart/src/bindings/bindings.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
import 'dart:ffi';
|
|
||||||
|
|
||||||
Matrix4 double4x4ToMatrix4(double4x4 mat) {
|
Matrix4 double4x4ToMatrix4(double4x4 mat) {
|
||||||
|
|
||||||
return Matrix4.fromList([
|
return Matrix4.fromList([
|
||||||
mat.col1[0],
|
mat.col1[0],
|
||||||
mat.col1[1],
|
mat.col1[1],
|
||||||
@@ -26,12 +25,16 @@ Matrix4 double4x4ToMatrix4(double4x4 mat) {
|
|||||||
|
|
||||||
double4x4 matrix4ToDouble4x4(Matrix4 mat) {
|
double4x4 matrix4ToDouble4x4(Matrix4 mat) {
|
||||||
final out = Struct.create<double4x4>();
|
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++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
out.col1[i] = mat.storage[i];
|
col1[i] = mat.storage[i];
|
||||||
out.col2[i] = mat.storage[i + 4];
|
col2[i] = mat.storage[i + 4];
|
||||||
out.col3[i] = mat.storage[i + 8];
|
col3[i] = mat.storage[i + 8];
|
||||||
out.col4[i] = mat.storage[i + 12];
|
col4[i] = mat.storage[i + 12];
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_scene.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_view.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_view.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
class TextureProjection {
|
class TextureProjection {
|
||||||
|
|||||||
@@ -1,20 +1,15 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'package:thermion_dart/src/filament/src/implementation/background_image.dart';
|
||||||
import 'dart:typed_data';
|
import '../../../../filament/src/implementation/ffi_asset.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/light_options.dart';
|
import 'package:thermion_dart/src/filament/src/implementation/ffi_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/background_image.dart';
|
import '../../../../filament/src/implementation/ffi_scene.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
import '../../../../filament/src/implementation/grid_overlay.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/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
import 'callbacks.dart';
|
import '../../../../filament/src/implementation/ffi_camera.dart';
|
||||||
import 'ffi_camera.dart';
|
import '../../../../filament/src/implementation/ffi_view.dart';
|
||||||
import 'ffi_view.dart';
|
|
||||||
|
|
||||||
const FILAMENT_ASSET_ERROR = 0;
|
const FILAMENT_ASSET_ERROR = 0;
|
||||||
|
|
||||||
@@ -50,6 +45,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future setViewport(int width, int height) async {
|
Future setViewport(int width, int height) async {
|
||||||
|
print("Setting viewport to ${width}x${height}");
|
||||||
await view.setViewport(width.toInt(), height.toInt());
|
await view.setViewport(width.toInt(), height.toInt());
|
||||||
|
|
||||||
for (final camera in _cameras) {
|
for (final camera in _cameras) {
|
||||||
@@ -121,8 +117,15 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future render() async {
|
Future render() async {
|
||||||
await withVoidCallback(
|
await withVoidCallback((cb) =>
|
||||||
(cb) => RenderTicker_renderRenderThread(app.renderTicker, 0, 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;
|
double _msPerFrame = 1000.0 / 60.0;
|
||||||
@@ -248,11 +251,21 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
|
Future loadIbl(String lightingPath, {double intensity = 30000}) async {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
var data = await loadAssetFromUri(lightingPath);
|
var data = await loadAssetFromUri(lightingPath);
|
||||||
|
|
||||||
indirectLight = await withPointerCallback<TIndirectLight>((cb) {
|
indirectLight = await withPointerCallback<TIndirectLight>((cb) {
|
||||||
Engine_buildIndirectLightRenderThread(
|
Engine_buildIndirectLightRenderThread(
|
||||||
app.engine, data.address, data.length, intensity, cb, nullptr);
|
app.engine, data.address, data.length, intensity, cb, nullptr);
|
||||||
});
|
});
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
data.free();
|
||||||
|
}
|
||||||
|
data.free();
|
||||||
Scene_setIndirectLight(scene.scene, indirectLight!);
|
Scene_setIndirectLight(scene.scene, indirectLight!);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +277,18 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
if (indirectLight == null) {
|
if (indirectLight == null) {
|
||||||
throw Exception("No IBL loaded");
|
throw Exception("No IBL loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
|
||||||
IndirectLight_setRotation(indirectLight!, rotationMatrix.storage.address);
|
IndirectLight_setRotation(indirectLight!, rotationMatrix.storage.address);
|
||||||
|
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
rotationMatrix.storage.free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -303,8 +327,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
|
Future<ThermionEntity> addDirectLight(DirectLight directLight) async {
|
||||||
var entity = LightManager_createLight(app.engine, app.lightManager,
|
var entity = LightManager_createLight(
|
||||||
TLightType.values[directLight.type.index]);
|
app.engine, app.lightManager, directLight.type.index);
|
||||||
if (entity == FILAMENT_ASSET_ERROR) {
|
if (entity == FILAMENT_ASSET_ERROR) {
|
||||||
throw Exception("Failed to add light to scene");
|
throw Exception("Failed to add light to scene");
|
||||||
}
|
}
|
||||||
@@ -446,8 +470,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
@override
|
@override
|
||||||
Future setPostProcessing(bool enabled) async {
|
Future setPostProcessing(bool enabled) async {
|
||||||
View_setPostProcessing(view.view, enabled);
|
View_setPostProcessing(view.view, enabled);
|
||||||
await withVoidCallback(
|
|
||||||
(cb) => Engine_flushAndWaitRenderThead(app.engine, cb));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -478,10 +500,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa) async {
|
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");
|
throw Exception("MSAA is not currently supported on Windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
View_setAntiAliasing(view.view, msaa, fxaa, taa);
|
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/interface/layers.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/light_options.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 'dart:typed_data';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
import 'dart:async';
|
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 'dart:js_interop';
|
||||||
|
|
||||||
import '../../../../filament/src/shared_types.dart';
|
import '../../../../filament/src/interface/shared_types.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
/// An extension type on [JSObject] that represents a
|
/// 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 'camera.dart';
|
||||||
// import 'material_instance.dart';
|
// import 'material_instance.dart';
|
||||||
|
|
||||||
// extension type _EmscriptenModule(JSObject _) implements JSObject {
|
extension type _EmscriptenModule(JSObject _) implements JSObject {
|
||||||
// external JSAny? ccall(String name, String returnType,
|
external JSAny? ccall(String name, String returnType,
|
||||||
// JSArray<JSString> argTypes, JSArray<JSAny?> args, JSAny? opts);
|
JSArray<JSString> argTypes, JSArray<JSAny?> args, JSAny? opts);
|
||||||
|
|
||||||
// external JSNumber _malloc(int numBytes);
|
external JSNumber _malloc(int numBytes);
|
||||||
// external void _free(JSNumber addr);
|
external void _free(JSNumber addr);
|
||||||
// external JSNumber stackAlloc(int numBytes);
|
external JSNumber stackAlloc(int numBytes);
|
||||||
|
|
||||||
// external JSAny getValue(JSNumber addr, String llvmType);
|
external JSAny getValue(JSNumber addr, String llvmType);
|
||||||
// external void setValue(JSNumber addr, JSNumber value, String llvmType);
|
external void setValue(JSNumber addr, JSNumber value, String llvmType);
|
||||||
|
|
||||||
// external JSString intArrayToString(JSAny ptr);
|
external JSString intArrayToString(JSAny ptr);
|
||||||
// external JSString UTF8ToString(JSAny ptr);
|
external JSString UTF8ToString(JSAny ptr);
|
||||||
// external void stringToUTF8(
|
external void stringToUTF8(
|
||||||
// JSString str, JSNumber ptr, JSNumber maxBytesToWrite);
|
JSString str, JSNumber ptr, JSNumber maxBytesToWrite);
|
||||||
// external void writeArrayToMemory(JSUint8Array data, JSNumber ptr);
|
external void writeArrayToMemory(JSUint8Array data, JSNumber ptr);
|
||||||
|
|
||||||
// external JSNumber addFunction(JSFunction f, String signature);
|
external JSNumber addFunction(JSFunction f, String signature);
|
||||||
// external void removeFunction(JSNumber f);
|
external void removeFunction(JSNumber f);
|
||||||
// external JSAny get ALLOC_STACK;
|
external JSAny get ALLOC_STACK;
|
||||||
// external JSAny get HEAPU32;
|
external JSAny get HEAPU32;
|
||||||
// external JSAny get HEAP32;
|
external JSAny get HEAP32;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// typedef ThermionViewerImpl = ThermionViewerWasm;
|
// typedef ThermionViewerImpl = ThermionViewerWasm;
|
||||||
|
|
||||||
@@ -80,7 +80,6 @@
|
|||||||
// _module = module as _EmscriptenModule;
|
// _module = module as _EmscriptenModule;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void _setAssetPathPrefix(String assetPathPrefix) {
|
// void _setAssetPathPrefix(String assetPathPrefix) {
|
||||||
// _module!.ccall(
|
// _module!.ccall(
|
||||||
// "thermion_dart_web_set_asset_path_prefix",
|
// "thermion_dart_web_set_asset_path_prefix",
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
library thermion_viewer;
|
library thermion_viewer;
|
||||||
|
|
||||||
export 'src/thermion_viewer_base.dart';
|
export 'src/thermion_viewer_base.dart';
|
||||||
export '../filament/src/filament_app.dart';
|
export '../filament/src/interface/filament_app.dart';
|
||||||
export 'src/thermion_viewer_stub.dart'
|
export 'src/ffi/src/thermion_viewer_ffi.dart';
|
||||||
if (dart.library.io) 'src/ffi/thermion_viewer_ffi.dart'
|
export '../filament/src/interface/shared_types.dart';
|
||||||
if (dart.library.js_interop) 'src/web_wasm/thermion_viewer_web_wasm.dart';
|
|
||||||
export '../filament/src/shared_types.dart';
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
library filament_dart;
|
library filament_dart;
|
||||||
|
|
||||||
|
export 'dart:typed_data';
|
||||||
export 'package:vector_math/vector_math_64.dart' hide Colors;
|
export 'package:vector_math/vector_math_64.dart' hide Colors;
|
||||||
export 'src/viewer/viewer.dart';
|
export 'src/viewer/viewer.dart';
|
||||||
export 'src/input/input.dart';
|
export 'src/input/input.dart';
|
||||||
export 'src/utils/utils.dart';
|
export 'src/utils/utils.dart';
|
||||||
export 'src/filament/filament.dart';
|
export 'src/filament/filament.dart';
|
||||||
|
export 'src/bindings/bindings.dart' hide Aabb2, Aabb3;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef FLUTTER_FILAMENT_LOG_H
|
#ifdef __EMSCRIPTEN__
|
||||||
#define FLUTTER_FILAMENT_LOG_H
|
#include <emscripten/console.h>
|
||||||
|
#endif
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#elif defined __ANDROID__
|
#elif defined __ANDROID__
|
||||||
@@ -14,6 +14,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#define Log(...) emscripten_console_logf(__VA_ARGS__);
|
||||||
|
#else
|
||||||
static void Log(const char *fmt, ...) {
|
static void Log(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@@ -26,11 +29,10 @@ static void Log(const char *fmt, ...) {
|
|||||||
#else
|
#else
|
||||||
vprintf(fmt, args);
|
vprintf(fmt, args);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||||
@@ -61,5 +63,3 @@ static void Log(const char *fmt, ...) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ERROR(fmt, ...) Log("Error: %s:%d " fmt, __FILENAME__, __LINE__, ##__VA_ARGS__)
|
#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
|
// Helper function to convert filament::math::mat4 to double4x4
|
||||||
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
|
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[0][0], mat[0][1], mat[0][2], mat[0][3]},
|
||||||
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
|
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
|
||||||
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
|
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ namespace thermion
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RenderTicker(filament::Renderer *renderer) : mRenderer(renderer) { }
|
RenderTicker(
|
||||||
|
filament::Engine *engine,
|
||||||
|
filament::Renderer *renderer) : mEngine(engine), mRenderer(renderer) { }
|
||||||
~RenderTicker();
|
~RenderTicker();
|
||||||
|
|
||||||
/// @brief
|
/// @brief
|
||||||
@@ -55,6 +57,7 @@ namespace thermion
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
|
filament::Engine *mEngine = nullptr;
|
||||||
filament::Renderer *mRenderer = nullptr;
|
filament::Renderer *mRenderer = nullptr;
|
||||||
std::vector<AnimationManager*> mAnimationManagers;
|
std::vector<AnimationManager*> mAnimationManagers;
|
||||||
std::vector<std::pair<filament::SwapChain*, std::vector<filament::View*>>> mRenderable;
|
std::vector<std::pair<filament::SwapChain*, std::vector<filament::View*>>> mRenderable;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "APIExport.h"
|
#include "APIExport.h"
|
||||||
@@ -156,6 +157,7 @@ extern "C"
|
|||||||
GIZMO_TYPE_TRANSLATION,
|
GIZMO_TYPE_TRANSLATION,
|
||||||
GIZMO_TYPE_ROTATION
|
GIZMO_TYPE_ROTATION
|
||||||
};
|
};
|
||||||
|
typedef enum TGizmoType TGizmoType;
|
||||||
|
|
||||||
enum TPrimitiveType {
|
enum TPrimitiveType {
|
||||||
// don't change the enums values (made to match GL)
|
// don't change the enums values (made to match GL)
|
||||||
@@ -165,11 +167,12 @@ extern "C"
|
|||||||
PRIMITIVETYPE_TRIANGLES = 4, //!< triangles
|
PRIMITIVETYPE_TRIANGLES = 4, //!< triangles
|
||||||
PRIMITIVETYPE_TRIANGLE_STRIP = 5 //!< triangle strip
|
PRIMITIVETYPE_TRIANGLE_STRIP = 5 //!< triangle strip
|
||||||
};
|
};
|
||||||
|
typedef enum TPrimitiveType TPrimitiveType;
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT;
|
extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT;
|
||||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_READABLE;
|
extern uint64_t TSWAP_CHAIN_CONFIG_READABLE;
|
||||||
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
|
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_HAS_STENCIL_BUFFER;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef _API_EXPORT_H
|
#pragma once
|
||||||
#define _API_EXPORT_H
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef IS_DLL
|
#ifdef IS_DLL
|
||||||
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
|
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
|
||||||
@@ -44,4 +44,3 @@
|
|||||||
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
|
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
@@ -13,37 +13,38 @@ enum TProjection {
|
|||||||
Perspective,
|
Perspective,
|
||||||
Orthographic
|
Orthographic
|
||||||
};
|
};
|
||||||
|
typedef enum TProjection TProjection;
|
||||||
|
|
||||||
// Camera methods
|
// Camera methods
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera *const camera);
|
double4x4 Camera_getModelMatrix(TCamera *const camera);
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getProjectionMatrix(TCamera *const camera);
|
double4x4 Camera_getProjectionMatrix(TCamera *const camera);
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera);
|
double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *camera, double* out);
|
void Camera_getFrustum(TCamera *camera, double* out);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjectionMatrix(TCamera *camera, double *matrix, double near, double far);
|
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);
|
void Camera_setProjectionFromFov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
|
double Camera_getFocalLength(TCamera *const camera);
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
|
double4x4 Camera_getViewMatrix(TCamera *const camera);
|
||||||
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
|
double4x4 Camera_getModelMatrix(TCamera* camera);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_lookAt(TCamera* camera, double3 eye, double3 focus, double3 up);
|
void Camera_lookAt(TCamera* camera, double3 eye, double3 focus, double3 up);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *camera);
|
double Camera_getNear(TCamera *camera);
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *camera);
|
double Camera_getCullingFar(TCamera *camera);
|
||||||
EMSCRIPTEN_KEEPALIVE float Camera_getFov(TCamera *camera, bool horizontal);
|
float Camera_getFov(TCamera *camera, bool horizontal);
|
||||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocusDistance(TCamera *camera);
|
double Camera_getFocusDistance(TCamera *camera);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setFocusDistance(TCamera *camera, float focusDistance);
|
void Camera_setFocusDistance(TCamera *camera, float focusDistance);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(
|
void Camera_setCustomProjectionWithCulling(
|
||||||
TCamera* camera,
|
TCamera* camera,
|
||||||
double4x4 projectionMatrix,
|
double4x4 projectionMatrix,
|
||||||
double near,
|
double near,
|
||||||
double far
|
double far
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix);
|
void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
|
EntityId Camera_getEntity(TCamera* camera);
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
|
void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
|
||||||
double bottom, double top,
|
double bottom, double top,
|
||||||
double near, double far);
|
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_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.
|
BACKEND_NOOP = 4, //!< Selects the no-op driver for testing purposes.
|
||||||
};
|
};
|
||||||
|
typedef enum TBackend TBackend;
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
|
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
|
||||||
TBackend backend,
|
TBackend backend,
|
||||||
@@ -50,6 +51,7 @@ EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTex
|
|||||||
EMSCRIPTEN_KEEPALIVE TFence *Engine_createFence(TEngine *tEngine);
|
EMSCRIPTEN_KEEPALIVE TFence *Engine_createFence(TEngine *tEngine);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyFence(TEngine *tEngine, TFence *tFence);
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyFence(TEngine *tEngine, TFence *tFence);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWait(TEngine *tEngine);
|
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 TMaterial *Engine_buildMaterial(TEngine *tEngine, const uint8_t* materialData, size_t length);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tMaterial);
|
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tMaterial);
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ extern "C"
|
|||||||
|
|
||||||
enum TGizmoAxis { X, Y, Z };
|
enum TGizmoAxis { X, Y, Z };
|
||||||
enum TGizmoPickResultType { AxisX, AxisY, AxisZ, Parent, None };
|
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);
|
typedef void (*GizmoPickCallback)(TGizmoPickResultType resultType, float x, float y, float z);
|
||||||
|
void Gizmo_dummy(TGizmoPickResultType t);
|
||||||
EMSCRIPTEN_KEEPALIVE TGizmo *Gizmo_create(
|
EMSCRIPTEN_KEEPALIVE TGizmo *Gizmo_create(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TGltfAssetLoader *assetLoader,
|
TGltfAssetLoader *assetLoader,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ extern "C"
|
|||||||
LIGHT_TYPE_FOCUSED_SPOT,
|
LIGHT_TYPE_FOCUSED_SPOT,
|
||||||
LIGHT_TYPE_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_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);
|
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.
|
A, //!< Always. Depth / stencil testing is deactivated.
|
||||||
N //!< Never. The depth / stencil test always fails.
|
N //!< Never. The depth / stencil test always fails.
|
||||||
};
|
};
|
||||||
|
typedef enum TSamplerCompareFunc TSamplerCompareFunc;
|
||||||
|
|
||||||
// StencilOperation equivalent
|
// StencilOperation equivalent
|
||||||
enum TStencilOperation
|
enum TStencilOperation
|
||||||
@@ -34,6 +35,7 @@ extern "C"
|
|||||||
DECR_WRAP, // Decrement the current value without saturation
|
DECR_WRAP, // Decrement the current value without saturation
|
||||||
INVERT // Invert the current value
|
INVERT // Invert the current value
|
||||||
};
|
};
|
||||||
|
typedef enum TStencilOperation TStencilOperation;
|
||||||
|
|
||||||
enum TStencilFace
|
enum TStencilFace
|
||||||
{
|
{
|
||||||
@@ -41,6 +43,7 @@ extern "C"
|
|||||||
STENCIL_FACE_BACK = 2,
|
STENCIL_FACE_BACK = 2,
|
||||||
STENCIL_FACE_FRONT_AND_BACK = 3
|
STENCIL_FACE_FRONT_AND_BACK = 3
|
||||||
};
|
};
|
||||||
|
typedef enum TStencilFace TStencilFace;
|
||||||
|
|
||||||
enum TCullingMode
|
enum TCullingMode
|
||||||
{
|
{
|
||||||
@@ -49,6 +52,7 @@ extern "C"
|
|||||||
CULLING_MODE_BACK,
|
CULLING_MODE_BACK,
|
||||||
CULLING_MODE_FRONT_AND_BACK
|
CULLING_MODE_FRONT_AND_BACK
|
||||||
};
|
};
|
||||||
|
typedef enum TCullingMode TCullingMode;
|
||||||
|
|
||||||
enum TTransparencyMode {
|
enum TTransparencyMode {
|
||||||
//! the transparent object is drawn honoring the raster state
|
//! the transparent object is drawn honoring the raster state
|
||||||
@@ -66,6 +70,7 @@ extern "C"
|
|||||||
*/
|
*/
|
||||||
TWO_PASSES_TWO_SIDES
|
TWO_PASSES_TWO_SIDES
|
||||||
};
|
};
|
||||||
|
typedef enum TTransparencyMode TTransparencyMode;
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
|
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine);
|
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#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_destroy(TRenderTicker *tRenderTicker);
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_addAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_addAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_removeAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
EMSCRIPTEN_KEEPALIVE void RenderTicker_removeAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "APIExport.h"
|
#include "APIExport.h"
|
||||||
#include "APIBoundaryTypes.h"
|
#include "APIBoundaryTypes.h"
|
||||||
#include "TMaterialInstance.h"
|
#include "TMaterialInstance.h"
|
||||||
|
#include "TTexture.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ enum TTextureSamplerType
|
|||||||
SAMPLER_CUBEMAP_ARRAY=5
|
SAMPLER_CUBEMAP_ARRAY=5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum TTextureSamplerType TTextureSamplerType;
|
||||||
|
|
||||||
enum TTextureFormat
|
enum TTextureFormat
|
||||||
{
|
{
|
||||||
// 8-bits per element
|
// 8-bits per element
|
||||||
@@ -157,6 +159,7 @@ enum TTextureFormat
|
|||||||
TEXTUREFORMAT_RGBA_BPTC_UNORM, // BC7
|
TEXTUREFORMAT_RGBA_BPTC_UNORM, // BC7
|
||||||
TEXTUREFORMAT_SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
|
TEXTUREFORMAT_SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
|
||||||
};
|
};
|
||||||
|
typedef enum TTextureFormat TTextureFormat;
|
||||||
|
|
||||||
//! Pixel Data Format
|
//! Pixel Data Format
|
||||||
enum TPixelDataFormat {
|
enum TPixelDataFormat {
|
||||||
@@ -173,6 +176,7 @@ enum TPixelDataFormat {
|
|||||||
PIXELDATAFORMAT_DEPTH_STENCIL, //!< Two Depth (24-bits) + Stencil (8-bits) channels
|
PIXELDATAFORMAT_DEPTH_STENCIL, //!< Two Depth (24-bits) + Stencil (8-bits) channels
|
||||||
PIXELDATAFORMAT_ALPHA //! One Alpha channel, float
|
PIXELDATAFORMAT_ALPHA //! One Alpha channel, float
|
||||||
};
|
};
|
||||||
|
typedef enum TPixelDataFormat TPixelDataFormat;
|
||||||
|
|
||||||
enum TPixelDataType {
|
enum TPixelDataType {
|
||||||
PIXELDATATYPE_UBYTE, //!< unsigned byte
|
PIXELDATATYPE_UBYTE, //!< unsigned byte
|
||||||
@@ -188,6 +192,7 @@ enum TPixelDataType {
|
|||||||
PIXELDATATYPE_USHORT_565, //!< unsigned int (16-bit), encodes 3 RGB channels
|
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
|
PIXELDATATYPE_UINT_2_10_10_10_REV, //!< unsigned normalized 10 bits RGB, 2 bits alpha
|
||||||
};
|
};
|
||||||
|
typedef enum TPixelDataType TPixelDataType;
|
||||||
|
|
||||||
enum TTextureUsage {
|
enum TTextureUsage {
|
||||||
TEXTURE_USAGE_NONE = 0x0000,
|
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_PROTECTED = 0x0100, //!< Texture can be used the destination of a blit()
|
||||||
TEXTURE_USAGE_DEFAULT = TEXTURE_USAGE_UPLOADABLE | TEXTURE_USAGE_SAMPLEABLE //!< Default texture usage
|
TEXTURE_USAGE_DEFAULT = TEXTURE_USAGE_UPLOADABLE | TEXTURE_USAGE_SAMPLEABLE //!< Default texture usage
|
||||||
};
|
};
|
||||||
|
typedef enum TTextureUsage TTextureUsage;
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TTexture *Texture_build(TEngine *engine,
|
EMSCRIPTEN_KEEPALIVE TTexture *Texture_build(TEngine *engine,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
@@ -268,6 +274,7 @@ enum TSamplerWrapMode {
|
|||||||
WRAP_REPEAT, // Repeat wrapping mode
|
WRAP_REPEAT, // Repeat wrapping mode
|
||||||
WRAP_MIRRORED_REPEAT // Mirrored repeat wrapping mode
|
WRAP_MIRRORED_REPEAT // Mirrored repeat wrapping mode
|
||||||
};
|
};
|
||||||
|
typedef enum TSamplerWrapMode TSamplerWrapMode;
|
||||||
|
|
||||||
enum TSamplerMinFilter {
|
enum TSamplerMinFilter {
|
||||||
FILTER_NEAREST, // Nearest filtering
|
FILTER_NEAREST, // Nearest filtering
|
||||||
@@ -277,16 +284,19 @@ enum TSamplerMinFilter {
|
|||||||
FILTER_NEAREST_MIPMAP_LINEAR, // Nearest mipmap linear filtering
|
FILTER_NEAREST_MIPMAP_LINEAR, // Nearest mipmap linear filtering
|
||||||
FILTER_LINEAR_MIPMAP_LINEAR // Linear mipmap linear filtering
|
FILTER_LINEAR_MIPMAP_LINEAR // Linear mipmap linear filtering
|
||||||
};
|
};
|
||||||
|
typedef enum TSamplerMinFilter TSamplerMinFilter;
|
||||||
|
|
||||||
enum TSamplerMagFilter {
|
enum TSamplerMagFilter {
|
||||||
MAG_FILTER_NEAREST, // Nearest filtering
|
MAG_FILTER_NEAREST, // Nearest filtering
|
||||||
MAG_FILTER_LINEAR // Linear filtering
|
MAG_FILTER_LINEAR // Linear filtering
|
||||||
};
|
};
|
||||||
|
typedef enum TSamplerMagFilter TSamplerMagFilter;
|
||||||
|
|
||||||
enum TSamplerCompareMode {
|
enum TSamplerCompareMode {
|
||||||
COMPARE_MODE_NONE, // No comparison
|
COMPARE_MODE_NONE, // No comparison
|
||||||
COMPARE_MODE_COMPARE_TO_TEXTURE // Compare to texture
|
COMPARE_MODE_COMPARE_TO_TEXTURE // Compare to texture
|
||||||
};
|
};
|
||||||
|
typedef enum TSamplerCompareMode TSamplerCompareMode;
|
||||||
|
|
||||||
typedef TSamplerCompareFunc TTextureSamplerCompareFunc ;
|
typedef TSamplerCompareFunc TTextureSamplerCompareFunc ;
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ enum TToneMapping
|
|||||||
FILMIC,
|
FILMIC,
|
||||||
LINEAR
|
LINEAR
|
||||||
};
|
};
|
||||||
|
typedef enum TToneMapping TToneMapping;
|
||||||
|
|
||||||
// copied from Options.h
|
// copied from Options.h
|
||||||
enum TQualityLevel {
|
enum TQualityLevel {
|
||||||
@@ -31,11 +32,13 @@ enum TQualityLevel {
|
|||||||
HIGH,
|
HIGH,
|
||||||
ULTRA
|
ULTRA
|
||||||
};
|
};
|
||||||
|
typedef enum TQualityLevel TQualityLevel;
|
||||||
|
|
||||||
enum TBlendMode {
|
enum TBlendMode {
|
||||||
OPAQUE,
|
OPAQUE,
|
||||||
TRANSLUCENT
|
TRANSLUCENT
|
||||||
};
|
};
|
||||||
|
typedef enum TBlendMode TBlendMode;
|
||||||
|
|
||||||
// View
|
// View
|
||||||
EMSCRIPTEN_KEEPALIVE TViewport View_getViewport(TView *view);
|
EMSCRIPTEN_KEEPALIVE TViewport View_getViewport(TView *view);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "TEngine.h"
|
||||||
#include "TView.h"
|
#include "TView.h"
|
||||||
#include "TTexture.h"
|
#include "TTexture.h"
|
||||||
#include "TMaterialProvider.h"
|
#include "TMaterialProvider.h"
|
||||||
@@ -10,20 +11,20 @@ namespace thermion
|
|||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
typedef void (*VoidCallback)();
|
||||||
typedef int32_t EntityId;
|
typedef int32_t EntityId;
|
||||||
typedef void (*FilamentRenderCallback)(void *const owner);
|
typedef void (*FilamentRenderCallback)(void *const owner);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderThread_create();
|
void RenderThread_create();
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderThread_destroy();
|
void RenderThread_destroy();
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderThread_requestFrame(void (*onComplete)());
|
void RenderThread_requestFrameAsync();
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderThread_setRenderTicker(TRenderTicker *tRenderTicker);
|
void RenderThread_setRenderTicker(TRenderTicker *tRenderTicker);
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderThread_addTask(void (*task)());
|
void RenderThread_addTask(void (*task)());
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, void (*onComplete)());
|
void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
|
void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_createRenderThread(
|
void Engine_createRenderThread(
|
||||||
TBackend backend,
|
TBackend backend,
|
||||||
void* platform,
|
void* platform,
|
||||||
void* sharedContext,
|
void* sharedContext,
|
||||||
@@ -31,22 +32,22 @@ namespace thermion
|
|||||||
bool disableHandleUseAfterFreeCheck,
|
bool disableHandleUseAfterFreeCheck,
|
||||||
void (*onComplete)(TEngine *)
|
void (*onComplete)(TEngine *)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *));
|
void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_createSwapChainRenderThread(TEngine *tEngine, void *window, uint64_t flags, void (*onComplete)(TSwapChain *));
|
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 *));
|
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 *));
|
void Engine_createCameraRenderThread(TEngine* tEngine, void (*onComplete)(TCamera *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_createViewRenderThread(TEngine *tEngine, void (*onComplete)(TView *));
|
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 *));
|
void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyRenderThread(TEngine *tEngine, void (*onComplete)());
|
void Engine_destroyRenderThread(TEngine *tEngine, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, void (*onComplete)());
|
void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, void (*onComplete)());
|
void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)());
|
void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, void (*onComplete)());
|
void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)());
|
void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, void (*onComplete)());
|
void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, void (*onComplete)());
|
void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, void (*onComplete)());
|
void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine,
|
void Texture_buildRenderThread(TEngine *engine,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height,
|
uint32_t height,
|
||||||
uint32_t depth,
|
uint32_t depth,
|
||||||
@@ -58,19 +59,20 @@ namespace thermion
|
|||||||
void (*onComplete)(TTexture*)
|
void (*onComplete)(TTexture*)
|
||||||
);
|
);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, void (*onComplete)());
|
void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
|
void Engine_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, void (*onComplete)());
|
void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWaitRenderThead(TEngine *tEngine, void (*onComplete)());
|
void Engine_flushAndWaitRenderThread(TEngine *tEngine, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_buildSkyboxRenderThread(TEngine *tEngine, uint8_t *skyboxData, size_t length, void (*onComplete)(TSkybox *), void (*onTextureUploadComplete)());
|
void Engine_executeRenderThread(TEngine *tEngine, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightRenderThread(TEngine *tEngine, uint8_t *iblData, size_t length, float intensity, void (*onComplete)(TIndirectLight *), void (*onTextureUploadComplete)());
|
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)());
|
void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));
|
void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));
|
||||||
EMSCRIPTEN_KEEPALIVE void Renderer_endFrameRenderThread(TRenderer *tRenderer, void (*onComplete)());
|
void Renderer_endFrameRenderThread(TRenderer *tRenderer, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)());
|
void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)());
|
void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Renderer_readPixelsRenderThread(
|
void Renderer_readPixelsRenderThread(
|
||||||
TRenderer *tRenderer,
|
TRenderer *tRenderer,
|
||||||
TView *tView,
|
TView *tView,
|
||||||
TRenderTarget *tRenderTarget,
|
TRenderTarget *tRenderTarget,
|
||||||
@@ -78,29 +80,29 @@ namespace thermion
|
|||||||
TPixelDataType tPixelDataType,
|
TPixelDataType tPixelDataType,
|
||||||
uint8_t *out,
|
uint8_t *out,
|
||||||
size_t outLength,
|
size_t outLength,
|
||||||
void (*onComplete)());
|
VoidCallback onComplete);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *));
|
void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
|
void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Material_createGizmoMaterialRenderThread(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 *));
|
void ColorGrading_createRenderThread(TEngine *tEngine, TToneMapping toneMapping, void (*callback)(TColorGrading *));
|
||||||
EMSCRIPTEN_KEEPALIVE void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, void (*callback)());
|
void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, void (*callback)());
|
void View_setBloomRenderThread(TView *tView, bool enabled, double strength, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, void (*callback)());
|
void View_setCameraRenderThread(TView *tView, TCamera *tCamera, VoidCallback onComplete);
|
||||||
|
|
||||||
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)());
|
void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
|
void SceneAsset_createFromFilamentAssetRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TGltfAssetLoader *tAssetLoader,
|
TGltfAssetLoader *tAssetLoader,
|
||||||
TNameComponentManager *tNameComponentManager,
|
TNameComponentManager *tNameComponentManager,
|
||||||
TFilamentAsset *tFilamentAsset,
|
TFilamentAsset *tFilamentAsset,
|
||||||
void (*onComplete)(TSceneAsset *)
|
void (*onComplete)(TSceneAsset *)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
|
void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
|
||||||
EMSCRIPTEN_KEEPALIVE void SceneAsset_createGeometryRenderThread(
|
void SceneAsset_createGeometryRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
float *vertices,
|
float *vertices,
|
||||||
uint32_t numVertices,
|
uint32_t numVertices,
|
||||||
@@ -115,14 +117,14 @@ namespace thermion
|
|||||||
int materialInstanceCount,
|
int materialInstanceCount,
|
||||||
void (*callback)(TSceneAsset *)
|
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,
|
TAnimationManager *tAnimationManager,
|
||||||
TSceneAsset *sceneAsset,
|
TSceneAsset *sceneAsset,
|
||||||
void (*callback)(bool));
|
void (*callback)(bool));
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setMorphTargetWeightsRenderThread(
|
void AnimationManager_setMorphTargetWeightsRenderThread(
|
||||||
TAnimationManager *tAnimationManager,
|
TAnimationManager *tAnimationManager,
|
||||||
EntityId entityId,
|
EntityId entityId,
|
||||||
const float *const morphData,
|
const float *const morphData,
|
||||||
@@ -130,16 +132,16 @@ namespace thermion
|
|||||||
void (*callback)(bool));
|
void (*callback)(bool));
|
||||||
|
|
||||||
// Image methods
|
// Image methods
|
||||||
EMSCRIPTEN_KEEPALIVE void Image_createEmptyRenderThread(uint32_t width, uint32_t height, uint32_t channel, void (*onComplete)(TLinearImage *));
|
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 *));
|
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 *));
|
void Image_getBytesRenderThread(TLinearImage *tLinearImage, void (*onComplete)(float *));
|
||||||
EMSCRIPTEN_KEEPALIVE void Image_destroyRenderThread(TLinearImage *tLinearImage, void (*onComplete)());
|
void Image_destroyRenderThread(TLinearImage *tLinearImage, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Image_getWidthRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
void Image_getWidthRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||||
EMSCRIPTEN_KEEPALIVE void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||||
EMSCRIPTEN_KEEPALIVE void Image_getChannelsRenderThread(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,
|
TEngine *tEngine,
|
||||||
TTexture *tTexture,
|
TTexture *tTexture,
|
||||||
TLinearImage *tImage,
|
TLinearImage *tImage,
|
||||||
@@ -147,7 +149,7 @@ namespace thermion
|
|||||||
TPixelDataType pixelDataType,
|
TPixelDataType pixelDataType,
|
||||||
void (*onComplete)(bool)
|
void (*onComplete)(bool)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void Texture_setImageRenderThread(
|
void Texture_setImageRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TTexture *tTexture,
|
TTexture *tTexture,
|
||||||
uint32_t level,
|
uint32_t level,
|
||||||
@@ -160,7 +162,7 @@ namespace thermion
|
|||||||
uint32_t pixelDataType,
|
uint32_t pixelDataType,
|
||||||
void (*onComplete)(bool)
|
void (*onComplete)(bool)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread(
|
void Texture_setImageWithDepthRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TTexture *tTexture,
|
TTexture *tTexture,
|
||||||
uint32_t level,
|
uint32_t level,
|
||||||
@@ -177,8 +179,8 @@ namespace thermion
|
|||||||
uint32_t pixelDataType,
|
uint32_t pixelDataType,
|
||||||
void (*onComplete)(bool)
|
void (*onComplete)(bool)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *));
|
void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *));
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_createRenderThread(
|
void RenderTarget_createRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height,
|
uint32_t height,
|
||||||
@@ -186,16 +188,16 @@ namespace thermion
|
|||||||
TTexture *depth,
|
TTexture *depth,
|
||||||
void (*onComplete)(TRenderTarget *)
|
void (*onComplete)(TRenderTarget *)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderTarget_destroyRenderThread(
|
void RenderTarget_destroyRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TRenderTarget *tRenderTarget,
|
TRenderTarget *tRenderTarget,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// TextureSampler methods
|
// TextureSampler methods
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*));
|
void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*));
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_createWithFilteringRenderThread(
|
void TextureSampler_createWithFilteringRenderThread(
|
||||||
TSamplerMinFilter minFilter,
|
TSamplerMinFilter minFilter,
|
||||||
TSamplerMagFilter magFilter,
|
TSamplerMagFilter magFilter,
|
||||||
TSamplerWrapMode wrapS,
|
TSamplerWrapMode wrapS,
|
||||||
@@ -203,53 +205,53 @@ namespace thermion
|
|||||||
TSamplerWrapMode wrapR,
|
TSamplerWrapMode wrapR,
|
||||||
void (*onComplete)(TTextureSampler*)
|
void (*onComplete)(TTextureSampler*)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_createWithComparisonRenderThread(
|
void TextureSampler_createWithComparisonRenderThread(
|
||||||
TSamplerCompareMode compareMode,
|
TSamplerCompareMode compareMode,
|
||||||
TSamplerCompareFunc compareFunc,
|
TSamplerCompareFunc compareFunc,
|
||||||
void (*onComplete)(TTextureSampler*)
|
void (*onComplete)(TTextureSampler*)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMinFilterRenderThread(
|
void TextureSampler_setMinFilterRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
TSamplerMinFilter filter,
|
TSamplerMinFilter filter,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMagFilterRenderThread(
|
void TextureSampler_setMagFilterRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
TSamplerMagFilter filter,
|
TSamplerMagFilter filter,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeSRenderThread(
|
void TextureSampler_setWrapModeSRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
TSamplerWrapMode mode,
|
TSamplerWrapMode mode,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeTRenderThread(
|
void TextureSampler_setWrapModeTRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
TSamplerWrapMode mode,
|
TSamplerWrapMode mode,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeRRenderThread(
|
void TextureSampler_setWrapModeRRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
TSamplerWrapMode mode,
|
TSamplerWrapMode mode,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setAnisotropyRenderThread(
|
void TextureSampler_setAnisotropyRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
double anisotropy,
|
double anisotropy,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_setCompareModeRenderThread(
|
void TextureSampler_setCompareModeRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
TSamplerCompareMode mode,
|
TSamplerCompareMode mode,
|
||||||
TTextureSamplerCompareFunc func,
|
TTextureSamplerCompareFunc func,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void TextureSampler_destroyRenderThread(
|
void TextureSampler_destroyRenderThread(
|
||||||
TTextureSampler* sampler,
|
TTextureSampler* sampler,
|
||||||
void (*onComplete)()
|
VoidCallback onComplete
|
||||||
);
|
);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setBoneTransformRenderThread(
|
void AnimationManager_setBoneTransformRenderThread(
|
||||||
TAnimationManager *tAnimationManager,
|
TAnimationManager *tAnimationManager,
|
||||||
EntityId asset,
|
EntityId asset,
|
||||||
int skinIndex,
|
int skinIndex,
|
||||||
@@ -257,18 +259,18 @@ namespace thermion
|
|||||||
const float *const transform,
|
const float *const transform,
|
||||||
void (*callback)(bool));
|
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 *));
|
void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
|
void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)());
|
void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
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)());
|
void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncUpdateLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader);
|
void GltfResourceLoader_asyncUpdateLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader);
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncGetLoadProgressRenderThread(TGltfResourceLoader *tGltfResourceLoader, void (*callback)(float));
|
void GltfResourceLoader_asyncGetLoadProgressRenderThread(TGltfResourceLoader *tGltfResourceLoader, void (*callback)(float));
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread(
|
void GltfAssetLoader_loadRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TGltfAssetLoader *tAssetLoader,
|
TGltfAssetLoader *tAssetLoader,
|
||||||
uint8_t *data,
|
uint8_t *data,
|
||||||
@@ -276,8 +278,8 @@ namespace thermion
|
|||||||
uint8_t numInstances,
|
uint8_t numInstances,
|
||||||
void (*callback)(TFilamentAsset *)
|
void (*callback)(TFilamentAsset *)
|
||||||
);
|
);
|
||||||
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, void (*callback)());
|
void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, VoidCallback onComplete);
|
||||||
EMSCRIPTEN_KEEPALIVE void Gizmo_createRenderThread(
|
void Gizmo_createRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
TGltfAssetLoader *tAssetLoader,
|
TGltfAssetLoader *tAssetLoader,
|
||||||
TGltfResourceLoader *tGltfResourceLoader,
|
TGltfResourceLoader *tGltfResourceLoader,
|
||||||
|
|||||||
@@ -3,11 +3,15 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
extern const uint8_t CAPTURE_UV_PACKAGE[];
|
extern const uint8_t CAPTURE_UV_PACKAGE[];
|
||||||
extern int CAPTURE_UV_CAPTURE_UV_OFFSET;
|
extern int CAPTURE_UV_CAPTURE_UV_OFFSET;
|
||||||
extern int CAPTURE_UV_CAPTURE_UV_SIZE;
|
extern int CAPTURE_UV_CAPTURE_UV_SIZE;
|
||||||
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#define CAPTURE_UV_CAPTURE_UV_DATA (CAPTURE_UV_PACKAGE + CAPTURE_UV_CAPTURE_UV_OFFSET)
|
#define CAPTURE_UV_CAPTURE_UV_DATA (CAPTURE_UV_PACKAGE + CAPTURE_UV_CAPTURE_UV_OFFSET)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,15 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
extern const uint8_t GRID_PACKAGE[];
|
extern const uint8_t GRID_PACKAGE[];
|
||||||
extern int GRID_GRID_OFFSET;
|
extern int GRID_GRID_OFFSET;
|
||||||
extern int GRID_GRID_SIZE;
|
extern int GRID_GRID_SIZE;
|
||||||
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#define GRID_GRID_DATA (GRID_PACKAGE + GRID_GRID_OFFSET)
|
#define GRID_GRID_DATA (GRID_PACKAGE + GRID_GRID_OFFSET)
|
||||||
|
|
||||||
#endif
|
#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