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,30 +1,90 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
CallbackHolder(this.nativeCallable);
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
nativeCallable.close();
|
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(
|
||||||
Function(Pointer<NativeFunction<Void Function()>>) func) async {
|
Function(Pointer<NativeFunction<Void Function()>>) func) async {
|
||||||
@@ -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);
|
||||||
await imageMaterialInstance.setParameterMat4(
|
var transform = Matrix4.identity();
|
||||||
"transform", Matrix4.identity());
|
|
||||||
|
|
||||||
backgroundImage.setMaterialInstanceAt(imageMaterialInstance);
|
await imageMaterialInstance.setParameterMat4(
|
||||||
|
"transform", transform);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (_childEntities == null) {
|
||||||
var count = SceneAsset_getChildEntityCount(asset);
|
var count = SceneAsset_getChildEntityCount(asset);
|
||||||
var children = Int32List(count);
|
var childEntities = Int32List(count);
|
||||||
SceneAsset_getChildEntities(asset, children.address);
|
late Pointer stackPtr;
|
||||||
return children;
|
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,8 +129,12 @@ 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 (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
|
||||||
if (materialInstances != null && materialInstances.isNotEmpty) {
|
if (materialInstances != null && materialInstances.isNotEmpty) {
|
||||||
ptrList.setRange(
|
ptrList.setRange(
|
||||||
0,
|
0,
|
||||||
@@ -130,12 +145,16 @@ class FFIAsset extends ThermionAsset {
|
|||||||
.toList());
|
.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,16 +784,27 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
int layer = 0,
|
int layer = 0,
|
||||||
String? relativeResourcePath,
|
String? relativeResourcePath,
|
||||||
bool loadResourcesAsync = false}) async {
|
bool loadResourcesAsync = false}) async {
|
||||||
|
final resources = <FinalizableUint8List>[];
|
||||||
|
try {
|
||||||
|
late Pointer stackPtr;
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackPtr = stackSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadResourcesAsync = FILAMENT_SINGLE_THREADED;
|
||||||
|
|
||||||
if (relativeResourcePath != null && !relativeResourcePath.endsWith("/")) {
|
if (relativeResourcePath != null && !relativeResourcePath.endsWith("/")) {
|
||||||
relativeResourcePath = "$relativeResourcePath/";
|
relativeResourcePath = "$relativeResourcePath/";
|
||||||
}
|
}
|
||||||
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
var gltfResourceLoader = await withPointerCallback<TGltfResourceLoader>(
|
||||||
(cb) => GltfResourceLoader_createRenderThread(engine,
|
(cb) => GltfResourceLoader_createRenderThread(
|
||||||
relativeResourcePath?.toNativeUtf8().cast<Char>() ?? nullptr, cb));
|
engine,
|
||||||
|
relativeResourcePath?.toNativeUtf8().cast<Char>() ?? nullptr,
|
||||||
|
cb));
|
||||||
|
|
||||||
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
||||||
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader, data.address,
|
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader,
|
||||||
data.length, numInstances, cb));
|
data.address, data.length, numInstances, cb));
|
||||||
|
|
||||||
if (filamentAsset == nullptr) {
|
if (filamentAsset == nullptr) {
|
||||||
throw Exception("An error occurred loading the asset");
|
throw Exception("An error occurred loading the asset");
|
||||||
@@ -776,7 +812,6 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
var resourceUris = FilamentAsset_getResourceUris(filamentAsset);
|
var resourceUris = FilamentAsset_getResourceUris(filamentAsset);
|
||||||
var resourceUriCount = FilamentAsset_getResourceUriCount(filamentAsset);
|
var resourceUriCount = FilamentAsset_getResourceUriCount(filamentAsset);
|
||||||
final resources = <FinalizableUint8List>[];
|
|
||||||
|
|
||||||
for (int i = 0; i < resourceUriCount; i++) {
|
for (int i = 0; i < resourceUriCount; i++) {
|
||||||
final resourceUriDart = resourceUris[i].cast<Utf8>().toDartString();
|
final resourceUriDart = resourceUris[i].cast<Utf8>().toDartString();
|
||||||
@@ -795,17 +830,23 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
cb));
|
cb));
|
||||||
}
|
}
|
||||||
if (loadResourcesAsync) {
|
if (loadResourcesAsync) {
|
||||||
final result = await withBoolCallback((cb) => GltfResourceLoader_asyncBeginLoadRenderThread(gltfResourceLoader, filamentAsset, cb));
|
final result = await withBoolCallback((cb) =>
|
||||||
|
GltfResourceLoader_asyncBeginLoadRenderThread(
|
||||||
|
gltfResourceLoader, filamentAsset, cb));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw Exception("Failed to begin async loading");
|
throw Exception("Failed to begin async loading");
|
||||||
}
|
}
|
||||||
|
|
||||||
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
||||||
|
|
||||||
var progress = await withFloatCallback((cb) => GltfResourceLoader_asyncGetLoadProgressRenderThread(gltfResourceLoader, cb));
|
var progress = await withFloatCallback((cb) =>
|
||||||
|
GltfResourceLoader_asyncGetLoadProgressRenderThread(
|
||||||
|
gltfResourceLoader, cb));
|
||||||
while (progress < 1.0) {
|
while (progress < 1.0) {
|
||||||
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
GltfResourceLoader_asyncUpdateLoadRenderThread(gltfResourceLoader);
|
||||||
progress = await withFloatCallback((cb) => GltfResourceLoader_asyncGetLoadProgressRenderThread(gltfResourceLoader, cb));
|
progress = await withFloatCallback((cb) =>
|
||||||
|
GltfResourceLoader_asyncGetLoadProgressRenderThread(
|
||||||
|
gltfResourceLoader, cb));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final result = await withBoolCallback((cb) =>
|
final result = await withBoolCallback((cb) =>
|
||||||
@@ -817,12 +858,22 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final asset = await withPointerCallback<TSceneAsset>((cb) =>
|
final asset = await withPointerCallback<TSceneAsset>((cb) =>
|
||||||
SceneAsset_createFromFilamentAssetRenderThread(
|
SceneAsset_createFromFilamentAssetRenderThread(engine,
|
||||||
engine, gltfAssetLoader, nameComponentManager, filamentAsset, cb));
|
gltfAssetLoader, nameComponentManager, filamentAsset, cb));
|
||||||
|
|
||||||
|
await withVoidCallback((cb) => GltfResourceLoader_destroyRenderThread(
|
||||||
|
engine, gltfResourceLoader, cb));
|
||||||
|
|
||||||
await withVoidCallback((cb) =>
|
|
||||||
GltfResourceLoader_destroyRenderThread(engine, gltfResourceLoader, cb));
|
|
||||||
return FFIAsset(asset, this, animationManager.cast<TAnimationManager>());
|
return FFIAsset(asset, this, animationManager.cast<TAnimationManager>());
|
||||||
|
} finally {
|
||||||
|
if (FILAMENT_WASM) {
|
||||||
|
//stackRestore(stackPtr);
|
||||||
|
data.free();
|
||||||
|
for (final resource in resources) {
|
||||||
|
resource.data.free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future destroyView(covariant FFIView view) async {
|
Future destroyView(covariant FFIView view) async {
|
||||||
@@ -839,6 +890,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
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,9 +968,13 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
final ptrList = IntPtrList(materialInstances?.length ?? 0);
|
||||||
|
if (materialInstances != null) {
|
||||||
ptrList.setRange(
|
ptrList.setRange(
|
||||||
0,
|
0,
|
||||||
materialInstances.length,
|
materialInstances.length,
|
||||||
@@ -917,7 +984,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
.toList());
|
.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
return SceneAsset_createGeometryRenderThread(
|
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,7 +1021,12 @@ 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((cb) =>
|
||||||
|
RenderTicker_renderRenderThread(app.renderTicker, 0.toBigInt, cb));
|
||||||
|
if (FILAMENT_SINGLE_THREADED) {
|
||||||
await withVoidCallback(
|
await withVoidCallback(
|
||||||
(cb) => RenderTicker_renderRenderThread(app.renderTicker, 0, cb));
|
(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);
|
||||||
@@ -27,10 +30,9 @@ static void Log(const char *fmt, ...) {
|
|||||||
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
|
|
||||||
@@ -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
@@ -3,11 +3,15 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
extern const uint8_t IMAGE_PACKAGE[];
|
extern const uint8_t IMAGE_PACKAGE[];
|
||||||
extern int IMAGE_IMAGE_OFFSET;
|
extern int IMAGE_IMAGE_OFFSET;
|
||||||
extern int IMAGE_IMAGE_SIZE;
|
extern int IMAGE_IMAGE_SIZE;
|
||||||
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#define IMAGE_IMAGE_DATA (IMAGE_PACKAGE + IMAGE_IMAGE_OFFSET)
|
#define IMAGE_IMAGE_DATA (IMAGE_PACKAGE + IMAGE_IMAGE_OFFSET)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user