chore: rearrange library/export structure
This commit is contained in:
85
thermion_dart/lib/src/viewer/src/events.dart
Normal file
85
thermion_dart/lib/src/viewer/src/events.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'shared_types/shared_types.dart';
|
||||
|
||||
///
|
||||
/// To ensure we can easily store/recreate a particular, [ThermionViewer] will raise an event whenever an
|
||||
/// entity is added/removed.
|
||||
///
|
||||
enum EventType { EntityAdded, EntityRemoved, EntityHidden, EntityRevealed, ClearLights }
|
||||
|
||||
///
|
||||
/// An "entity added" event must provide sufficient detail to enable that asset to be reloaded in future.
|
||||
/// This requires a bit more legwork because entities may be lights (direct/indirect), geometry or gltf.
|
||||
///
|
||||
enum EntityType { Geometry, Gltf, DirectLight, IBL }
|
||||
|
||||
class SceneUpdateEvent {
|
||||
late final ThermionEntity? entity;
|
||||
late final EventType eventType;
|
||||
|
||||
EntityType get addedEntityType {
|
||||
if (_directLight != null) {
|
||||
return EntityType.DirectLight;
|
||||
} else if (_ibl != null) {
|
||||
return EntityType.IBL;
|
||||
} else if (_gltf != null) {
|
||||
return EntityType.Gltf;
|
||||
} else if (_geometry != null) {
|
||||
return EntityType.Geometry;
|
||||
} else {
|
||||
throw Exception("Unknown entity type");
|
||||
}
|
||||
}
|
||||
|
||||
DirectLight? _directLight;
|
||||
IBL? _ibl;
|
||||
GLTF? _gltf;
|
||||
Geometry? _geometry;
|
||||
|
||||
SceneUpdateEvent.remove(this.entity) {
|
||||
this.eventType = EventType.EntityRemoved;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.reveal(this.entity) {
|
||||
this.eventType = EventType.EntityRevealed;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.hide(this.entity) {
|
||||
this.eventType = EventType.EntityHidden;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.addDirectLight(this.entity, this._directLight) {
|
||||
this.eventType = EventType.EntityAdded;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.addIbl(this.entity, this._ibl) {
|
||||
this.eventType = EventType.EntityAdded;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.addGltf(this.entity, this._gltf) {
|
||||
this.eventType = EventType.EntityAdded;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.addGeometry(this.entity, this._geometry) {
|
||||
this.eventType = EventType.EntityAdded;
|
||||
}
|
||||
|
||||
SceneUpdateEvent.clearLights() {
|
||||
this.eventType = EventType.ClearLights;
|
||||
}
|
||||
|
||||
DirectLight getDirectLight() {
|
||||
return _directLight!;
|
||||
}
|
||||
|
||||
IBL getAsIBL() {
|
||||
return _ibl!;
|
||||
}
|
||||
|
||||
GLTF getAsGLTF() {
|
||||
return _gltf!;
|
||||
}
|
||||
|
||||
Geometry getAsGeometry() {
|
||||
return _geometry!;
|
||||
}
|
||||
}
|
||||
89
thermion_dart/lib/src/viewer/src/ffi/src/callbacks.dart
Normal file
89
thermion_dart/lib/src/viewer/src/ffi/src/callbacks.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
export 'package:ffi/ffi.dart';
|
||||
export 'dart:ffi';
|
||||
export 'thermion_dart.g.dart';
|
||||
|
||||
final allocator = calloc;
|
||||
|
||||
void using(Pointer ptr, Future Function(Pointer ptr) function) async {
|
||||
await function.call(ptr);
|
||||
allocator.free(ptr);
|
||||
}
|
||||
|
||||
Future<void> withVoidCallback(
|
||||
Function(Pointer<NativeFunction<Void Function()>>) func) async {
|
||||
final completer = Completer();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function() callback = () {
|
||||
completer.complete();
|
||||
};
|
||||
final nativeCallable = NativeCallable<Void Function()>.listener(callback);
|
||||
func.call(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
nativeCallable.close();
|
||||
}
|
||||
|
||||
Future<int> 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<NativeType>) callback = (Pointer<NativeType> ptr) {
|
||||
completer.complete(ptr.cast<T>());
|
||||
};
|
||||
final nativeCallable =
|
||||
NativeCallable<Void Function(Pointer<NativeType>)>.listener(callback);
|
||||
func.call(nativeCallable.nativeFunction);
|
||||
var ptr = await completer.future;
|
||||
nativeCallable.close();
|
||||
return ptr.address;
|
||||
}
|
||||
|
||||
Future<bool> withBoolCallback(
|
||||
Function(Pointer<NativeFunction<Void Function(Bool)>>) func) async {
|
||||
final completer = Completer<bool>();
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
void Function(bool) callback = (bool result) {
|
||||
completer.complete(result);
|
||||
};
|
||||
final nativeCallable = NativeCallable<Void Function(Bool)>.listener(callback);
|
||||
func.call(nativeCallable.nativeFunction);
|
||||
await completer.future;
|
||||
nativeCallable.close();
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
54
thermion_dart/lib/src/viewer/src/ffi/src/camera_ffi.dart
Normal file
54
thermion_dart/lib/src/viewer/src/ffi/src/camera_ffi.dart
Normal file
@@ -0,0 +1,54 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../../../utils/matrix.dart';
|
||||
import '../../shared_types/camera.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
import 'thermion_dart.g.dart';
|
||||
|
||||
class ThermionFFICamera extends Camera {
|
||||
final Pointer<TCamera> camera;
|
||||
final Pointer<TEngine> engine;
|
||||
late ThermionEntity _entity;
|
||||
|
||||
ThermionFFICamera(this.camera, this.engine) {
|
||||
_entity = Camera_getEntity(camera);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far) async {
|
||||
Camera_setCustomProjectionWithCulling(
|
||||
camera, matrix4ToDouble4x4(projectionMatrix), near, far);
|
||||
}
|
||||
|
||||
Future<Matrix4> getModelMatrix() async {
|
||||
return double4x4ToMatrix4(Camera_getModelMatrix(camera));
|
||||
}
|
||||
|
||||
@override
|
||||
Future setTransform(Matrix4 transform) async {
|
||||
var entity = Camera_getEntity(camera);
|
||||
Engine_setTransform(engine, entity, matrix4ToDouble4x4(transform));
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLensProjection(
|
||||
{double near = kNear,
|
||||
double far = kFar,
|
||||
double aspect = 1.0,
|
||||
double focalLength = kFocalLength}) async {
|
||||
Camera_setLensProjection(camera, near, far, aspect, focalLength);
|
||||
}
|
||||
|
||||
@override
|
||||
ThermionEntity getEntity() {
|
||||
return _entity;
|
||||
}
|
||||
|
||||
@override
|
||||
Future setModelMatrix(Matrix4 matrix) async {
|
||||
Camera_setModelMatrix(camera, matrix4ToDouble4x4(matrix));
|
||||
}
|
||||
}
|
||||
2199
thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart
Normal file
2199
thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart
Normal file
File diff suppressed because it is too large
Load Diff
2230
thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart
Normal file
2230
thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
library;
|
||||
|
||||
export 'src/thermion_viewer_ffi.dart' show ThermionViewerFFI;
|
||||
export 'src/camera_ffi.dart';
|
||||
21
thermion_dart/lib/src/viewer/src/shared_types/camera.dart
Normal file
21
thermion_dart/lib/src/viewer/src/shared_types/camera.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../thermion_viewer_base.dart';
|
||||
|
||||
abstract class Camera {
|
||||
Future setProjectionMatrixWithCulling(
|
||||
Matrix4 projectionMatrix, double near, double far);
|
||||
|
||||
Future setLensProjection(
|
||||
{double near = kNear,
|
||||
double far = kFar,
|
||||
double aspect = 1.0,
|
||||
double focalLength = kFocalLength});
|
||||
|
||||
Future<Matrix4> getModelMatrix();
|
||||
Future setModelMatrix(Matrix4 matrix);
|
||||
|
||||
ThermionEntity getEntity();
|
||||
|
||||
Future setTransform(Matrix4 transform);
|
||||
}
|
||||
11
thermion_dart/lib/src/viewer/src/shared_types/entities.dart
Normal file
11
thermion_dart/lib/src/viewer/src/shared_types/entities.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
library;
|
||||
|
||||
export 'geometry.dart';
|
||||
export 'gltf.dart';
|
||||
|
||||
export 'light_options.dart';
|
||||
|
||||
// a handle that can be safely passed back to the rendering layer to manipulate an Entity
|
||||
typedef ThermionEntity = int;
|
||||
|
||||
|
||||
32
thermion_dart/lib/src/viewer/src/shared_types/geometry.dart
Normal file
32
thermion_dart/lib/src/viewer/src/shared_types/geometry.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../../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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
6
thermion_dart/lib/src/viewer/src/shared_types/gltf.dart
Normal file
6
thermion_dart/lib/src/viewer/src/shared_types/gltf.dart
Normal file
@@ -0,0 +1,6 @@
|
||||
class GLTF {
|
||||
final String uri;
|
||||
final int numInstances;
|
||||
|
||||
GLTF(this.uri, this.numInstances);
|
||||
}
|
||||
7
thermion_dart/lib/src/viewer/src/shared_types/light.dart
Normal file
7
thermion_dart/lib/src/viewer/src/shared_types/light.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
enum LightType {
|
||||
SUN, //!< Directional light that also draws a sun's disk in the sky.
|
||||
DIRECTIONAL, //!< Directional light, emits light in a given direction.
|
||||
POINT, //!< Point light, emits light from a position, in all directions.
|
||||
FOCUSED_SPOT, //!< Physically correct spot light.
|
||||
SPOT,
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import 'dart:math';
|
||||
import 'package:vector_math/vector_math_64.dart' as v;
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'light.dart';
|
||||
|
||||
class IBL {
|
||||
String? iblPath;
|
||||
final double iblIntensity;
|
||||
|
||||
IBL(this.iblIntensity);
|
||||
}
|
||||
|
||||
class DirectLight {
|
||||
final LightType type;
|
||||
final double color;
|
||||
final double intensity;
|
||||
final bool castShadows;
|
||||
late final v.Vector3 position;
|
||||
late final v.Vector3 direction;
|
||||
final double falloffRadius;
|
||||
final double spotLightConeInner;
|
||||
final double spotLightConeOuter;
|
||||
final double sunAngularRadius;
|
||||
final double sunHaloSize;
|
||||
final double sunHaloFallof;
|
||||
|
||||
DirectLight({
|
||||
required this.type,
|
||||
required this.color,
|
||||
required this.intensity,
|
||||
this.castShadows = false,
|
||||
required this.direction,
|
||||
required this.position,
|
||||
this.falloffRadius = 1.0,
|
||||
this.spotLightConeInner = pi / 8,
|
||||
this.spotLightConeOuter = pi / 4,
|
||||
this.sunAngularRadius = 0.545,
|
||||
this.sunHaloSize = 10.0,
|
||||
this.sunHaloFallof = 80.0,
|
||||
});
|
||||
|
||||
DirectLight.point({
|
||||
double color = 6500,
|
||||
double intensity = 100000,
|
||||
bool castShadows = false,
|
||||
Vector3? position,
|
||||
double falloffRadius = 1.0,
|
||||
}) : this(
|
||||
type: LightType.POINT,
|
||||
color: color,
|
||||
intensity: intensity,
|
||||
castShadows: castShadows,
|
||||
position: position ?? Vector3(0, 1, 0),
|
||||
direction: Vector3.zero(),
|
||||
falloffRadius: falloffRadius,
|
||||
);
|
||||
|
||||
DirectLight.sun({
|
||||
double color = 6500,
|
||||
double intensity = 100000,
|
||||
bool castShadows = true,
|
||||
Vector3? direction,
|
||||
double sunAngularRadius = 0.545,
|
||||
double sunHaloSize = 10.0,
|
||||
double sunHaloFalloff = 80.0,
|
||||
}) : this(
|
||||
type: LightType.DIRECTIONAL,
|
||||
color: color,
|
||||
intensity: intensity,
|
||||
castShadows: castShadows,
|
||||
position: Vector3(0, 0, 0),
|
||||
direction: direction ?? Vector3(0, -1, 0),
|
||||
sunAngularRadius: sunAngularRadius,
|
||||
sunHaloSize: sunHaloSize,
|
||||
sunHaloFallof: sunHaloFalloff,
|
||||
);
|
||||
|
||||
DirectLight.spot({
|
||||
double color = 6500,
|
||||
double intensity = 100000,
|
||||
bool castShadows = true,
|
||||
Vector3? position,
|
||||
Vector3? direction,
|
||||
double falloffRadius = 1.0,
|
||||
double spotLightConeInner = pi / 8,
|
||||
double spotLightConeOuter = pi / 4,
|
||||
}) : this(
|
||||
type: LightType.SPOT,
|
||||
color: color,
|
||||
intensity: intensity,
|
||||
castShadows: castShadows,
|
||||
position: position ?? Vector3(0, 1, 0),
|
||||
direction: direction ?? Vector3(0, -1, 0),
|
||||
falloffRadius: falloffRadius,
|
||||
spotLightConeInner: spotLightConeInner,
|
||||
spotLightConeOuter: spotLightConeOuter,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// see filament Manipulator.h for more details
|
||||
@Deprecated(
|
||||
"This is used the native pointer manipulator Prefer InputHandler instead")
|
||||
enum ManipulatorMode { ORBIT, MAP, FREE_FLIGHT }
|
||||
@@ -0,0 +1,6 @@
|
||||
abstract class MaterialInstance {
|
||||
Future setDepthWriteEnabled(bool enabled);
|
||||
Future setDepthCullingEnabled(bool enabled);
|
||||
}
|
||||
|
||||
enum AlphaMode { OPAQUE, MASK, BLEND }
|
||||
@@ -0,0 +1,5 @@
|
||||
// "picking" means clicking/tapping on the viewport, and unprojecting the X/Y coordinate to determine whether any renderable entities were present at those coordinates.
|
||||
import '../../viewer.dart';
|
||||
|
||||
typedef FilamentPickResult = ({ThermionEntity entity, double x, double y});
|
||||
typedef ThermionPickResult = FilamentPickResult;
|
||||
10
thermion_dart/lib/src/viewer/src/shared_types/primitive.dart
Normal file
10
thermion_dart/lib/src/viewer/src/shared_types/primitive.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
// copied from filament/backened/DriverEnums.h
|
||||
enum PrimitiveType {
|
||||
// don't change the enums values (made to match GL)
|
||||
POINTS, //!< points
|
||||
LINES, //!< lines
|
||||
UNUSED1,
|
||||
LINE_STRIP, //!< line strip
|
||||
TRIANGLES, //!< triangles
|
||||
TRIANGLE_STRIP, //!< triangle strip
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
enum ShadowType {
|
||||
PCF, //!< percentage-closer filtered shadows (default)
|
||||
VSM, //!< variance shadows
|
||||
DPCF, //!< PCF with contact hardening simulation
|
||||
PCSS, //!< PCF with soft shadows and contact hardening
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
library shared_types;
|
||||
|
||||
export 'camera.dart';
|
||||
export 'material.dart';
|
||||
export 'texture.dart';
|
||||
export 'entities.dart';
|
||||
export 'light.dart';
|
||||
export 'shadow.dart';
|
||||
export 'manipulator.dart';
|
||||
export 'pick_result.dart';
|
||||
export 'primitive.dart';
|
||||
export 'texture_details.dart';
|
||||
export 'tone_mapper.dart';
|
||||
@@ -0,0 +1,3 @@
|
||||
abstract class ThermionTexture {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
///
|
||||
/// This represents the backing "surface" that we render into.
|
||||
/// "Texture" here is a misnomer as it is only a render target texture on certain platforms.
|
||||
///
|
||||
class TextureDetails {
|
||||
final int textureId;
|
||||
|
||||
// both width and height are in physical, not logical pixels
|
||||
final int width;
|
||||
final int height;
|
||||
|
||||
TextureDetails(
|
||||
{required this.textureId, required this.width, required this.height});
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
enum ToneMapper { ACES, FILMIC, LINEAR }
|
||||
982
thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart
Normal file
982
thermion_dart/lib/src/viewer/src/thermion_viewer_base.dart
Normal file
@@ -0,0 +1,982 @@
|
||||
import 'package:thermion_dart/src/viewer/src/events.dart';
|
||||
import '../../entities/abstract_gizmo.dart';
|
||||
import 'shared_types/camera.dart';
|
||||
import 'shared_types/shared_types.dart';
|
||||
export 'shared_types/shared_types.dart';
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:async';
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
|
||||
const double kNear = 0.05;
|
||||
const double kFar = 1000.0;
|
||||
const double kFocalLength = 28.0;
|
||||
|
||||
abstract class ThermionViewer {
|
||||
///
|
||||
/// A Future that resolves when the underlying rendering context has been successfully created.
|
||||
///
|
||||
Future<bool> get initialized;
|
||||
|
||||
///
|
||||
/// The current dimensions of the viewport (in physical pixels).
|
||||
///
|
||||
var viewportDimensions = (0.0, 0.0);
|
||||
|
||||
///
|
||||
/// The current ratio of logical to physical pixels.
|
||||
///
|
||||
late double pixelRatio;
|
||||
|
||||
///
|
||||
/// The result(s) of calling [pick] (see below).
|
||||
/// This may be a broadcast stream, so you should ensure you have subscribed to this stream before calling [pick].
|
||||
/// If [pick] is called without an active subscription to this stream, the results will be silently discarded.
|
||||
///
|
||||
Stream<FilamentPickResult> get pickResult;
|
||||
|
||||
///
|
||||
/// The result(s) of calling [pickGizmo] (see below).
|
||||
///
|
||||
Stream<FilamentPickResult> get gizmoPickResult;
|
||||
|
||||
///
|
||||
/// A Stream containing entities added/removed to/from to the scene.
|
||||
///
|
||||
Stream<SceneUpdateEvent> get sceneUpdated;
|
||||
|
||||
///
|
||||
/// Whether the controller is currently rendering at [framerate].
|
||||
///
|
||||
bool get rendering;
|
||||
|
||||
///
|
||||
/// Set to true to continuously render the scene at the framerate specified by [setFrameRate] (60 fps by default).
|
||||
///
|
||||
Future setRendering(bool render);
|
||||
|
||||
///
|
||||
/// Render a single frame immediately.
|
||||
///
|
||||
Future render();
|
||||
|
||||
///
|
||||
/// Requests a single frame to be rendered. This is only intended to be used internally.
|
||||
///
|
||||
Future requestFrame();
|
||||
|
||||
///
|
||||
/// Render a single frame and copy the pixel buffer to [out].
|
||||
///
|
||||
Future<Uint8List> capture();
|
||||
|
||||
///
|
||||
/// Sets the framerate for continuous rendering when [setRendering] is enabled.
|
||||
///
|
||||
Future setFrameRate(int framerate);
|
||||
|
||||
///
|
||||
/// Destroys/disposes the viewer (including the entire scene). You cannot use the viewer after calling this method.
|
||||
///
|
||||
Future dispose();
|
||||
|
||||
///
|
||||
/// Set the background image to [path] (which should have a file extension .png, .jpg, or .ktx).
|
||||
/// This will be rendered at the maximum depth (i.e. behind all other objects including the skybox).
|
||||
/// If [fillHeight] is false, the image will be rendered at its original size. Note this may cause issues with pixel density so be sure to specify the correct resolution
|
||||
/// If [fillHeight] is true, the image will be stretched/compressed to fit the height of the viewport.
|
||||
///
|
||||
Future setBackgroundImage(String path, {bool fillHeight = false});
|
||||
|
||||
///
|
||||
/// Moves the background image to the relative offset from the origin (bottom-left) specified by [x] and [y].
|
||||
/// If [clamp] is true, the image cannot be positioned outside the bounds of the viewport.
|
||||
///
|
||||
Future setBackgroundImagePosition(double x, double y, {bool clamp = false});
|
||||
|
||||
///
|
||||
/// Removes the background image.
|
||||
///
|
||||
Future clearBackgroundImage();
|
||||
|
||||
///
|
||||
/// Sets the color for the background plane (positioned at the maximum depth, i.e. behind all other objects including the skybox).
|
||||
///
|
||||
Future setBackgroundColor(double r, double g, double b, double alpha);
|
||||
|
||||
///
|
||||
/// Load a skybox from [skyboxPath] (which must be a .ktx file)
|
||||
///
|
||||
Future loadSkybox(String skyboxPath);
|
||||
|
||||
///
|
||||
/// Removes the skybox from the scene.
|
||||
///
|
||||
Future removeSkybox();
|
||||
|
||||
///
|
||||
/// Creates an indirect light by loading the reflections/irradiance from the KTX file.
|
||||
/// Only one indirect light can be active at any given time; if an indirect light has already been loaded, it will be replaced.
|
||||
///
|
||||
Future loadIbl(String lightingPath, {double intensity = 30000});
|
||||
|
||||
///
|
||||
/// Creates a indirect light with the given color.
|
||||
/// Only one indirect light can be active at any given time; if an indirect light has already been loaded, it will be replaced.
|
||||
///
|
||||
Future createIbl(double r, double g, double b, double intensity);
|
||||
|
||||
///
|
||||
/// Rotates the IBL & skybox.
|
||||
///
|
||||
Future rotateIbl(Matrix3 rotation);
|
||||
|
||||
///
|
||||
/// Removes the image-based light from the scene.
|
||||
///
|
||||
Future removeIbl();
|
||||
|
||||
///
|
||||
/// Add a light to the scene.
|
||||
/// See LightManager.h for details
|
||||
/// Note that [sunAngularRadius] is in degrees,
|
||||
/// whereas [spotLightConeInner] and [spotLightConeOuter] are in radians
|
||||
///
|
||||
@Deprecated(
|
||||
"This will be removed in future versions. Use addDirectLight instead.")
|
||||
Future<ThermionEntity> addLight(
|
||||
LightType type,
|
||||
double colour,
|
||||
double intensity,
|
||||
double posX,
|
||||
double posY,
|
||||
double posZ,
|
||||
double dirX,
|
||||
double dirY,
|
||||
double dirZ,
|
||||
{double falloffRadius = 1.0,
|
||||
double spotLightConeInner = pi / 8,
|
||||
double spotLightConeOuter = pi / 4,
|
||||
double sunAngularRadius = 0.545,
|
||||
double sunHaloSize = 10.0,
|
||||
double sunHaloFallof = 80.0,
|
||||
bool castShadows = true});
|
||||
|
||||
///
|
||||
/// Adds a direct light to the scene.
|
||||
/// See LightManager.h for details
|
||||
/// Note that [sunAngularRadius] is in degrees,
|
||||
/// whereas [spotLightConeInner] and [spotLightConeOuter] are in radians
|
||||
///
|
||||
Future<ThermionEntity> addDirectLight(DirectLight light);
|
||||
|
||||
///
|
||||
/// Remove a light from the scene.
|
||||
///
|
||||
Future removeLight(ThermionEntity light);
|
||||
|
||||
///
|
||||
/// Remove all lights (excluding IBL) from the scene.
|
||||
///
|
||||
Future clearLights();
|
||||
|
||||
///
|
||||
/// Load the .glb asset at the given path and insert into the scene.
|
||||
/// Specify [numInstances] to create multiple instances (this is more efficient than dynamically instantating at a later time). You can then retrieve the created instances with [getInstances].
|
||||
/// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData].
|
||||
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
|
||||
///
|
||||
Future<ThermionEntity> loadGlb(String path,
|
||||
{int numInstances = 1, bool keepData = false});
|
||||
|
||||
///
|
||||
/// Load the .glb asset from the specified buffer and insert into the scene.
|
||||
/// Specify [numInstances] to create multiple instances (this is more efficient than dynamically instantating at a later time). You can then retrieve the created instances with [getInstances].
|
||||
/// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData].
|
||||
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
|
||||
///
|
||||
Future<ThermionEntity> loadGlbFromBuffer(Uint8List data,
|
||||
{int numInstances = 1,
|
||||
bool keepData = false,
|
||||
int priority = 4,
|
||||
int layer = 0});
|
||||
|
||||
///
|
||||
/// Create a new instance of [entity].
|
||||
///
|
||||
Future<ThermionEntity> createInstance(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Returns the number of instances of the asset associated with [entity].
|
||||
///
|
||||
Future<int> getInstanceCount(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Returns all instances of [entity].
|
||||
///
|
||||
Future<List<ThermionEntity>> getInstances(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Load the .gltf asset at the given path and insert into the scene.
|
||||
/// [relativeResourcePath] is the folder path where the glTF resources are stored;
|
||||
/// this is usually the parent directory of the .gltf file itself.
|
||||
///
|
||||
/// See [loadGlb] for an explanation of [keepData].
|
||||
///
|
||||
Future<ThermionEntity> loadGltf(String path, String relativeResourcePath,
|
||||
{bool keepData = false});
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panStart(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panUpdate(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future panEnd();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateStart(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateUpdate(double x, double y);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future rotateEnd();
|
||||
|
||||
///
|
||||
/// Set the weights for all morph targets in [entity] to [weights].
|
||||
/// Note that [weights] must contain values for ALL morph targets, but no exception will be thrown if you don't do so (you'll just get incorrect results).
|
||||
/// If you only want to set one value, set all others to zero (check [getMorphTargetNames] if you need the get a list of all morph targets).
|
||||
/// IMPORTANT - this accepts the actual ThermionEntity with the relevant morph targets (unlike [getMorphTargetNames], which uses the parent entity and the child mesh name).
|
||||
/// Use [getChildEntityByName] if you are setting the weights for a child mesh.
|
||||
///
|
||||
Future setMorphTargetWeights(ThermionEntity entity, List<double> weights);
|
||||
|
||||
///
|
||||
/// Gets the names of all morph targets for the child renderable [childEntity] under [entity].
|
||||
///
|
||||
Future<List<String>> getMorphTargetNames(
|
||||
ThermionEntity entity, ThermionEntity childEntity);
|
||||
|
||||
///
|
||||
/// Gets the names of all bones for the armature at [skinIndex] under the specified [entity].
|
||||
///
|
||||
Future<List<String>> getBoneNames(ThermionEntity entity, {int skinIndex = 0});
|
||||
|
||||
///
|
||||
/// Gets the names of all glTF animations embedded in the specified entity.
|
||||
///
|
||||
Future<List<String>> getAnimationNames(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Returns the length (in seconds) of the animation at the given index.
|
||||
///
|
||||
Future<double> getAnimationDuration(
|
||||
ThermionEntity entity, int animationIndex);
|
||||
|
||||
///
|
||||
/// Animate the morph targets in [entity]. See [MorphTargetAnimation] for an explanation as to how to construct the animation frame data.
|
||||
/// This method will check the morph target names specified in [animation] against the morph target names that actually exist exist under [meshName] in [entity],
|
||||
/// throwing an exception if any cannot be found.
|
||||
/// It is permissible for [animation] to omit any targets that do exist under [meshName]; these simply won't be animated.
|
||||
///
|
||||
Future setMorphAnimationData(
|
||||
ThermionEntity entity, MorphAnimationData animation,
|
||||
{List<String>? targetMeshNames});
|
||||
|
||||
///
|
||||
/// Clear all current morph animations for [entity].
|
||||
///
|
||||
Future clearMorphAnimationData(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Resets all bones in the given entity to their rest pose.
|
||||
/// This should be done before every call to addBoneAnimation.
|
||||
///
|
||||
Future resetBones(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Enqueues and plays the [animation] for the specified bone(s).
|
||||
/// By default, frame data is interpreted as being in *parent* bone space;
|
||||
/// a 45 degree around Y means the bone will rotate 45 degrees around the
|
||||
/// Y axis of the parent bone *in its current orientation*.
|
||||
/// (i.e NOT the parent bone's rest position!).
|
||||
/// Currently, only [Space.ParentBone] and [Space.Model] are supported; if you want
|
||||
/// to transform to another space, you will need to do so manually.
|
||||
///
|
||||
/// [fadeInInSecs]/[fadeOutInSecs]/[maxDelta] are used to cross-fade between
|
||||
/// the current active glTF animation ("animation1") and the animation you
|
||||
/// set via this method ("animation2"). The bone orientations will be
|
||||
/// linearly interpolated between animation1 and animation2; at time 0,
|
||||
/// the orientation will be 100% animation1, at time [fadeInInSecs], the
|
||||
/// animation will be ((1 - maxDelta) * animation1) + (maxDelta * animation2).
|
||||
/// This will be applied in reverse after [fadeOutInSecs].
|
||||
///
|
||||
///
|
||||
Future addBoneAnimation(ThermionEntity entity, BoneAnimationData animation,
|
||||
{int skinIndex = 0,
|
||||
double fadeInInSecs = 0.0,
|
||||
double fadeOutInSecs = 0.0,
|
||||
double maxDelta = 1.0});
|
||||
|
||||
///
|
||||
/// Gets the entity representing the bone at [boneIndex]/[skinIndex].
|
||||
/// The returned entity is only intended for use with [getWorldTransform].
|
||||
///
|
||||
Future<ThermionEntity> getBone(ThermionEntity parent, int boneIndex,
|
||||
{int skinIndex = 0});
|
||||
|
||||
///
|
||||
/// Gets the local (relative to parent) transform for [entity].
|
||||
///
|
||||
Future<Matrix4> getLocalTransform(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Gets the world transform for [entity].
|
||||
///
|
||||
Future<Matrix4> getWorldTransform(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Gets the inverse bind (pose) matrix for the bone.
|
||||
/// Note that [parent] must be the ThermionEntity returned by [loadGlb/loadGltf], not any other method ([getChildEntity] etc).
|
||||
/// This is because all joint information is internally stored with the parent entity.
|
||||
///
|
||||
Future<Matrix4> getInverseBindMatrix(ThermionEntity parent, int boneIndex,
|
||||
{int skinIndex = 0});
|
||||
|
||||
///
|
||||
/// Sets the transform (relative to its parent) for [entity].
|
||||
///
|
||||
Future setTransform(ThermionEntity entity, Matrix4 transform);
|
||||
|
||||
///
|
||||
/// Updates the bone matrices for [entity] (which must be the ThermionEntity
|
||||
/// returned by [loadGlb/loadGltf]).
|
||||
/// Under the hood, this just calls [updateBoneMatrices] on the Animator
|
||||
/// instance of the relevant FilamentInstance (which uses the local
|
||||
/// bone transform and the inverse bind matrix to set the bone matrix).
|
||||
///
|
||||
Future updateBoneMatrices(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Directly set the bone matrix for the bone at the given index.
|
||||
/// Don't call this manually unless you know what you're doing.
|
||||
///
|
||||
Future setBoneTransform(
|
||||
ThermionEntity entity, int boneIndex, Matrix4 transform,
|
||||
{int skinIndex = 0});
|
||||
|
||||
///
|
||||
/// Removes/destroys the specified entity from the scene.
|
||||
/// [entity] will no longer be a valid handle after this method is called; ensure you immediately discard all references once this method is complete.
|
||||
///
|
||||
Future removeEntity(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Removes/destroys all renderable entities from the scene (including cameras).
|
||||
/// All [ThermionEntity] handles will no longer be valid after this method is called; ensure you immediately discard all references to all entities once this method is complete.
|
||||
///
|
||||
Future clearEntities();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomBegin();
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomUpdate(double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Called by `FilamentGestureDetector`. You probably don't want to call this yourself.
|
||||
///
|
||||
Future zoomEnd();
|
||||
|
||||
///
|
||||
/// Schedules the glTF animation at [index] in [entity] to start playing on the next frame.
|
||||
///
|
||||
Future playAnimation(ThermionEntity entity, int index,
|
||||
{bool loop = false,
|
||||
bool reverse = false,
|
||||
bool replaceActive = true,
|
||||
double crossfade = 0.0,
|
||||
double startOffset = 0.0});
|
||||
|
||||
///
|
||||
/// Schedules the glTF animation at [index] in [entity] to start playing on the next frame.
|
||||
///
|
||||
Future playAnimationByName(ThermionEntity entity, String name,
|
||||
{bool loop = false,
|
||||
bool reverse = false,
|
||||
bool replaceActive = true,
|
||||
double crossfade = 0.0});
|
||||
|
||||
Future setAnimationFrame(
|
||||
ThermionEntity entity, int index, int animationFrame);
|
||||
|
||||
Future stopAnimation(ThermionEntity entity, int animationIndex);
|
||||
Future stopAnimationByName(ThermionEntity entity, String name);
|
||||
|
||||
///
|
||||
/// Sets the current scene camera to the glTF camera under [name] in [entity].
|
||||
///
|
||||
Future setCamera(ThermionEntity entity, String? name);
|
||||
|
||||
///
|
||||
/// Sets the current scene camera to the main camera (which is always available and added to every scene by default).
|
||||
///
|
||||
Future setMainCamera();
|
||||
|
||||
///
|
||||
/// Returns the entity associated with the main camera. You probably never need this; use getMainCamera instead.
|
||||
///
|
||||
Future<ThermionEntity> getMainCameraEntity();
|
||||
|
||||
///
|
||||
/// Returns the entity associated with the main camera. You probably never need this; use getMainCamera instead.
|
||||
///
|
||||
Future<Camera> getMainCamera();
|
||||
|
||||
///
|
||||
/// Sets the horizontal field of view (if [horizontal] is true) or vertical field of view for the currently active camera to [degrees].
|
||||
/// The aspect ratio of the current viewport is used.
|
||||
///
|
||||
Future setCameraFov(double degrees, {bool horizontal = true});
|
||||
|
||||
///
|
||||
/// Gets the field of view (in degrees).
|
||||
///
|
||||
Future<double> getCameraFov(bool horizontal);
|
||||
|
||||
///
|
||||
/// Sets the tone mapping (requires postprocessing).
|
||||
///
|
||||
Future setToneMapping(ToneMapper mapper);
|
||||
|
||||
///
|
||||
/// Sets the strength of the bloom.
|
||||
///
|
||||
Future setBloom(double bloom);
|
||||
|
||||
///
|
||||
/// Sets the focal length of the camera. Default value is 28.0.
|
||||
///
|
||||
Future setCameraFocalLength(double focalLength);
|
||||
|
||||
///
|
||||
/// Sets the distance (in world units) to the near/far planes for the active camera. Default values are 0.05/1000.0. See Camera.h for details.
|
||||
///
|
||||
Future setCameraCulling(double near, double far);
|
||||
|
||||
///
|
||||
/// Get the distance (in world units) to the near plane for the active camera.
|
||||
///
|
||||
@Deprecated("Use getCameraNear")
|
||||
Future<double> getCameraCullingNear();
|
||||
|
||||
///
|
||||
/// Get the distance (in world units) to the near plane for the active camera.
|
||||
///
|
||||
Future<double> getCameraNear();
|
||||
|
||||
///
|
||||
/// Get the distance (in world units) to the far culling plane for the active camera.
|
||||
///
|
||||
Future<double> getCameraCullingFar();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setCameraLensProjection(
|
||||
{double near = kNear,
|
||||
double far = kFar,
|
||||
double? aspect,
|
||||
double focalLength = kFocalLength});
|
||||
|
||||
///
|
||||
/// Sets the focus distance for the camera.
|
||||
///
|
||||
Future setCameraFocusDistance(double focusDistance);
|
||||
|
||||
///
|
||||
/// Get the camera position in world space.
|
||||
///
|
||||
Future<Vector3> getCameraPosition();
|
||||
|
||||
///
|
||||
/// Get the camera's model matrix.
|
||||
///
|
||||
Future<Matrix4> getCameraModelMatrix();
|
||||
|
||||
///
|
||||
/// Get the camera's view matrix. See Camera.h for more details.
|
||||
///
|
||||
Future<Matrix4> getCameraViewMatrix();
|
||||
|
||||
///
|
||||
/// Get the camera's projection matrix. See Camera.h for more details.
|
||||
///
|
||||
Future<Matrix4> getCameraProjectionMatrix();
|
||||
|
||||
///
|
||||
/// Get the camera's culling projection matrix. See Camera.h for more details.
|
||||
///
|
||||
Future<Matrix4> getCameraCullingProjectionMatrix();
|
||||
|
||||
///
|
||||
/// Get the camera's culling frustum in world space. Returns a (vector_math) [Frustum] instance where plane0-plane6 define the left, right, bottom, top, far and near planes respectively.
|
||||
/// See Camera.h and (filament) Frustum.h for more details.
|
||||
///
|
||||
Future<Frustum> getCameraFrustum();
|
||||
|
||||
///
|
||||
/// Set the camera position in world space. Note this is not persistent - any viewport navigation will reset the camera transform.
|
||||
///
|
||||
Future setCameraPosition(double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Get the camera rotation matrix.
|
||||
///
|
||||
Future<Matrix3> getCameraRotation();
|
||||
|
||||
///
|
||||
/// Repositions the camera to the last vertex of the bounding box of [entity], looking at the penultimate vertex.
|
||||
///
|
||||
Future moveCameraToAsset(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Enables/disables frustum culling.
|
||||
///
|
||||
Future setViewFrustumCulling(bool enabled);
|
||||
|
||||
///
|
||||
/// Sets the camera exposure.
|
||||
///
|
||||
Future setCameraExposure(
|
||||
double aperture, double shutterSpeed, double sensitivity);
|
||||
|
||||
///
|
||||
/// Rotate the camera by [rads] around the given axis.
|
||||
///
|
||||
Future setCameraRotation(Quaternion quaternion);
|
||||
|
||||
///
|
||||
/// Sets the camera model matrix.
|
||||
///
|
||||
@Deprecated("Will be superseded by setCameraModelMatrix4")
|
||||
Future setCameraModelMatrix(List<double> matrix);
|
||||
|
||||
///
|
||||
/// Sets the camera model matrix.
|
||||
///
|
||||
Future setCameraModelMatrix4(Matrix4 matrix);
|
||||
|
||||
///
|
||||
/// Sets the `baseColorFactor` property for the material at index [materialIndex] in [entity] under node [meshName] to [color].
|
||||
///
|
||||
@Deprecated("Use setMaterialPropertyFloat4 instead")
|
||||
Future setMaterialColor(ThermionEntity entity, String meshName,
|
||||
int materialIndex, double r, double g, double b, double a);
|
||||
|
||||
///
|
||||
/// Sets the material property [propertyName] under material [materialIndex] for [entity] to [value].
|
||||
/// [entity] must have a Renderable attached.
|
||||
///
|
||||
Future setMaterialPropertyFloat4(ThermionEntity entity, String propertyName,
|
||||
int materialIndex, double f1, double f2, double f3, double f4);
|
||||
|
||||
///
|
||||
/// Sets the material property [propertyName] under material [materialIndex] for [entity] to [value].
|
||||
/// [entity] must have a Renderable attached.
|
||||
///
|
||||
Future setMaterialPropertyFloat(ThermionEntity entity, String propertyName,
|
||||
int materialIndex, double value);
|
||||
|
||||
///
|
||||
/// Sets the material property [propertyName] under material [materialIndex] for [entity] to [value].
|
||||
/// [entity] must have a Renderable attached.
|
||||
///
|
||||
Future setMaterialPropertyInt(
|
||||
ThermionEntity entity, String propertyName, int materialIndex, int value);
|
||||
|
||||
///
|
||||
/// Scale [entity] to fit within the unit cube.
|
||||
///
|
||||
Future transformToUnitCube(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Directly sets the world space position for [entity] to the given coordinates.
|
||||
///
|
||||
Future setPosition(ThermionEntity entity, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Set the world space position for [lightEntity] to the given coordinates.
|
||||
///
|
||||
Future setLightPosition(
|
||||
ThermionEntity lightEntity, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Sets the world space direction for [lightEntity] to the given vector.
|
||||
///
|
||||
Future setLightDirection(ThermionEntity lightEntity, Vector3 direction);
|
||||
|
||||
///
|
||||
/// Directly sets the scale for [entity], skipping all collision detection.
|
||||
///
|
||||
Future setScale(ThermionEntity entity, double scale);
|
||||
|
||||
///
|
||||
/// Directly sets the rotation for [entity] to [rads] around the axis {x,y,z}, skipping all collision detection.
|
||||
///
|
||||
Future setRotation(
|
||||
ThermionEntity entity, double rads, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Queues an update to the worldspace position for [entity] to {x,y,z}.
|
||||
/// The actual update will occur on the next frame, and will be subject to collision detection.
|
||||
///
|
||||
Future queuePositionUpdate(
|
||||
ThermionEntity entity, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// TODO
|
||||
///
|
||||
Future queuePositionUpdateFromViewportCoords(
|
||||
ThermionEntity entity, double x, double y);
|
||||
|
||||
///
|
||||
/// TODO
|
||||
///
|
||||
Future queueRelativePositionUpdateWorldAxis(ThermionEntity entity,
|
||||
double viewportX, double viewportY, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Queues an update to the worldspace rotation for [entity].
|
||||
/// The actual update will occur on the next frame, and will be subject to collision detection.
|
||||
///
|
||||
Future queueRotationUpdate(
|
||||
ThermionEntity entity, double rads, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Same as [queueRotationUpdate].
|
||||
///
|
||||
Future queueRotationUpdateQuat(ThermionEntity entity, Quaternion quat,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Enable/disable postprocessing (disabled by default).
|
||||
///
|
||||
Future setPostProcessing(bool enabled);
|
||||
|
||||
///
|
||||
/// Enable/disable shadows (disabled by default).
|
||||
///
|
||||
Future setShadowsEnabled(bool enabled);
|
||||
|
||||
///
|
||||
/// Set shadow type.
|
||||
///
|
||||
Future setShadowType(ShadowType shadowType);
|
||||
|
||||
///
|
||||
/// Set soft shadow options (ShadowType DPCF and PCSS)
|
||||
///
|
||||
Future setSoftShadowOptions(double penumbraScale, double penumbraRatioScale);
|
||||
|
||||
///
|
||||
/// Set antialiasing options.
|
||||
///
|
||||
Future setAntiAliasing(bool msaa, bool fxaa, bool taa);
|
||||
|
||||
///
|
||||
/// Sets the rotation for [entity] to the specified quaternion.
|
||||
///
|
||||
Future setRotationQuat(ThermionEntity entity, Quaternion rotation);
|
||||
|
||||
///
|
||||
/// Reveal the node [meshName] under [entity]. Only applicable if [hide] had previously been called; this is a no-op otherwise.
|
||||
///
|
||||
Future reveal(ThermionEntity entity, String? meshName);
|
||||
|
||||
///
|
||||
/// If [meshName] is provided, hide the node [meshName] under [entity], otherwise hide the root node for [entity].
|
||||
/// The entity still exists in memory, but is no longer being rendered into the scene. Call [reveal] to re-commence rendering.
|
||||
///
|
||||
Future hide(ThermionEntity entity, String? meshName);
|
||||
|
||||
///
|
||||
/// Used to select the entity in the scene at the given viewport coordinates.
|
||||
/// Called by `FilamentGestureDetector` on a mouse/finger down event. You probably don't want to call this yourself.
|
||||
/// This is asynchronous and will require 2-3 frames to complete - subscribe to the [pickResult] stream to receive the results of this method.
|
||||
/// [x] and [y] must be in local logical coordinates (i.e. where 0,0 is at top-left of the ThermionWidget).
|
||||
///
|
||||
void pick(int x, int y);
|
||||
|
||||
///
|
||||
/// Used to test whether a Gizmo is at the given viewport coordinates.
|
||||
/// Called by `FilamentGestureDetector` on a mouse/finger down event. You probably don't want to call this yourself.
|
||||
/// This is asynchronous and will require 2-3 frames to complete - subscribe to the [gizmoPickResult] stream to receive the results of this method.
|
||||
/// [x] and [y] must be in local logical coordinates (i.e. where 0,0 is at top-left of the ThermionWidget).
|
||||
///
|
||||
void pickGizmo(int x, int y);
|
||||
|
||||
///
|
||||
/// Retrieves the name assigned to the given ThermionEntity (usually corresponds to the glTF mesh name).
|
||||
///
|
||||
String? getNameForEntity(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the options for manipulating the camera via the viewport.
|
||||
/// ManipulatorMode.FREE_FLIGHT and ManipulatorMode.MAP are currently unsupported and will throw an exception.
|
||||
///
|
||||
@Deprecated("Use InputHandler instead")
|
||||
Future setCameraManipulatorOptions(
|
||||
{ManipulatorMode mode = ManipulatorMode.ORBIT,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01});
|
||||
|
||||
///
|
||||
/// Returns all child entities under [parent].
|
||||
///
|
||||
Future<List<ThermionEntity>> getChildEntities(
|
||||
ThermionEntity parent, bool renderableOnly);
|
||||
|
||||
///
|
||||
/// Finds the child entity named [childName] associated with the given parent.
|
||||
/// Usually, [parent] will be the return value from [loadGlb]/[loadGltf] and [childName] will be the name of a node/mesh.
|
||||
///
|
||||
Future<ThermionEntity> getChildEntity(
|
||||
ThermionEntity parent, String childName);
|
||||
|
||||
///
|
||||
/// List the name of all child entities under the given entity.
|
||||
///
|
||||
Future<List<String>> getChildEntityNames(ThermionEntity entity,
|
||||
{bool renderableOnly = true});
|
||||
|
||||
///
|
||||
/// If [recording] is set to true, each frame the framebuffer/texture will be written to /tmp/output_*.png.
|
||||
/// This will impact performance; handle with care.
|
||||
///
|
||||
Future setRecording(bool recording);
|
||||
|
||||
///
|
||||
/// Sets the output directory where recorded PNGs will be placed.
|
||||
///
|
||||
Future setRecordingOutputDirectory(String outputDirectory);
|
||||
|
||||
///
|
||||
/// An [entity] will only be animatable after an animation component is attached.
|
||||
/// Any calls to [playAnimation]/[setBoneAnimation]/[setMorphAnimation] will have no visual effect until [addAnimationComponent] has been called on the instance.
|
||||
///
|
||||
Future addAnimationComponent(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Removes an animation component from [entity].
|
||||
///
|
||||
Future removeAnimationComponent(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Makes [entity] collidable.
|
||||
/// This allows you to call [testCollisions] with any other entity ("entity B") to see if [entity] has collided with entity B. The callback will be invoked if so.
|
||||
/// Alternatively, if [affectsTransform] is true and this entity collides with another entity, any queued position updates to the latter entity will be ignored.
|
||||
///
|
||||
Future addCollisionComponent(ThermionEntity entity,
|
||||
{void Function(int entityId1, int entityId2)? callback,
|
||||
bool affectsTransform = false});
|
||||
|
||||
///
|
||||
/// Removes the collision component from [entity], meaning this will no longer be tested when [testCollisions] or [queuePositionUpdate] is called with another entity.
|
||||
///
|
||||
Future removeCollisionComponent(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Creates a (renderable) entity with the specified geometry and adds to the scene.
|
||||
/// If [keepData] is true, the source data will not be released.
|
||||
///
|
||||
Future createGeometry(Geometry geometry,
|
||||
{MaterialInstance? materialInstance, bool keepData = false});
|
||||
|
||||
///
|
||||
/// Gets the parent entity of [entity]. Returns null if the entity has no parent.
|
||||
///
|
||||
Future<ThermionEntity?> getParent(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Gets the ancestor (ultimate parent) entity of [entity]. Returns null if the entity has no parent.
|
||||
///
|
||||
Future<ThermionEntity?> getAncestor(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the parent transform of [child] to [parent].
|
||||
///
|
||||
Future setParent(ThermionEntity child, ThermionEntity parent,
|
||||
{bool preserveScaling});
|
||||
|
||||
///
|
||||
/// Test all collidable entities against this entity to see if any have collided.
|
||||
/// This method returns void; the relevant callback passed to [addCollisionComponent] will be fired if a collision is detected.
|
||||
///
|
||||
Future testCollisions(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the draw priority for the given entity. See RenderableManager.h for more details.
|
||||
///
|
||||
Future setPriority(ThermionEntity entityId, int priority);
|
||||
|
||||
///
|
||||
/// The gizmo for translating/rotating objects. Only one gizmo is present in the scene.
|
||||
///
|
||||
AbstractGizmo? get gizmo;
|
||||
|
||||
///
|
||||
/// Register a callback to be invoked when this viewer is disposed.
|
||||
///
|
||||
void onDispose(Future Function() callback);
|
||||
|
||||
///
|
||||
/// Gets the 2D bounding box (in viewport coordinates) for the given entity.
|
||||
///
|
||||
Future<Aabb2> getViewportBoundingBox(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Filament assigns renderables to a numeric layer.
|
||||
/// We place all scene assets in layer 0 (enabled by default), gizmos in layer 1 (enabled by default), world grid in layer 2 (disabled by default).
|
||||
/// Use this method to toggle visibility of the respective layer.
|
||||
///
|
||||
Future setLayerVisibility(int layer, bool visible);
|
||||
|
||||
///
|
||||
/// Assigns [entity] to visibility layer [layer].
|
||||
///
|
||||
Future setVisibilityLayer(ThermionEntity entity, int layer);
|
||||
|
||||
///
|
||||
/// Show/hide the translation gizmo.
|
||||
///
|
||||
Future setGizmoVisibility(bool visible);
|
||||
|
||||
///
|
||||
/// Renders an outline around [entity] with the given color.
|
||||
///
|
||||
Future setStencilHighlight(ThermionEntity entity,
|
||||
{double r = 1.0, double g = 0.0, double b = 0.0});
|
||||
|
||||
///
|
||||
/// Removes the outline around [entity]. Noop if there was no highlight.
|
||||
///
|
||||
Future removeStencilHighlight(ThermionEntity entity);
|
||||
|
||||
///
|
||||
/// Decodes the specified image data and creates a texture.
|
||||
///
|
||||
Future<ThermionTexture> createTexture(Uint8List data);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future applyTexture(covariant ThermionTexture texture, ThermionEntity entity,
|
||||
{int materialIndex = 0, String parameterName = "baseColorMap"});
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future destroyTexture(covariant ThermionTexture texture);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<MaterialInstance> createUbershaderMaterialInstance({
|
||||
bool doubleSided = false,
|
||||
bool unlit = false,
|
||||
bool hasVertexColors = false,
|
||||
bool hasBaseColorTexture = false,
|
||||
bool hasNormalTexture = false,
|
||||
bool hasOcclusionTexture = false,
|
||||
bool hasEmissiveTexture = false,
|
||||
bool useSpecularGlossiness = false,
|
||||
AlphaMode alphaMode = AlphaMode.OPAQUE,
|
||||
bool enableDiagnostics = false,
|
||||
bool hasMetallicRoughnessTexture = false,
|
||||
int metallicRoughnessUV = 0,
|
||||
int baseColorUV = 0,
|
||||
bool hasClearCoatTexture = false,
|
||||
int clearCoatUV = 0,
|
||||
bool hasClearCoatRoughnessTexture = false,
|
||||
int clearCoatRoughnessUV = 0,
|
||||
bool hasClearCoatNormalTexture = false,
|
||||
int clearCoatNormalUV = 0,
|
||||
bool hasClearCoat = false,
|
||||
bool hasTransmission = false,
|
||||
bool hasTextureTransforms = false,
|
||||
int emissiveUV = 0,
|
||||
int aoUV = 0,
|
||||
int normalUV = 0,
|
||||
bool hasTransmissionTexture = false,
|
||||
int transmissionUV = 0,
|
||||
bool hasSheenColorTexture = false,
|
||||
int sheenColorUV = 0,
|
||||
bool hasSheenRoughnessTexture = false,
|
||||
int sheenRoughnessUV = 0,
|
||||
bool hasVolumeThicknessTexture = false,
|
||||
int volumeThicknessUV = 0,
|
||||
bool hasSheen = false,
|
||||
bool hasIOR = false,
|
||||
bool hasVolume = false,
|
||||
});
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future destroyMaterialInstance(covariant MaterialInstance materialInstance);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<MaterialInstance> createUnlitMaterialInstance();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<MaterialInstance?> getMaterialInstanceAt(
|
||||
ThermionEntity entity, int index);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Camera> createCamera();
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future setActiveCamera(covariant Camera camera);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future registerRequestFrameHook(Future Function() hook);
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future unregisterRequestFrameHook(Future Function() hook);
|
||||
}
|
||||
1000
thermion_dart/lib/src/viewer/src/thermion_viewer_stub.dart
Normal file
1000
thermion_dart/lib/src/viewer/src/thermion_viewer_stub.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,759 @@
|
||||
@JS()
|
||||
library thermion_flutter_js;
|
||||
|
||||
import 'dart:js_interop';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'dart:js_interop_unsafe';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import '../../../viewer.dart';
|
||||
import 'thermion_viewer_js_shim.dart';
|
||||
|
||||
///
|
||||
/// A (Dart) class that wraps a (Dart) instance of [ThermionViewer],
|
||||
/// but exported to JS by binding to a global property.
|
||||
/// This is effectively an implementation of [ThermionViewerJSShim];
|
||||
/// allowing users to interact with an instance of [ThermionViewer]
|
||||
/// (presumably compiled to WASM) from any Javascript context (including
|
||||
/// the browser console).
|
||||
///
|
||||
@JSExport()
|
||||
class ThermionViewerJSDartBridge {
|
||||
final _logger = Logger("ThermionViewerJSDartBridge");
|
||||
final ThermionViewer viewer;
|
||||
|
||||
ThermionViewerJSDartBridge(this.viewer);
|
||||
|
||||
void bind({String globalPropertyName = "thermionViewer"}) {
|
||||
var wrapper = createJSInteropWrapper<ThermionViewerJSDartBridge>(this)
|
||||
as ThermionViewerJSShim;
|
||||
globalContext.setProperty(globalPropertyName.toJS, wrapper);
|
||||
}
|
||||
|
||||
JSPromise<JSBoolean> get initialized {
|
||||
return viewer.initialized.then((v) => v.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSBoolean get rendering => viewer.rendering.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRendering(bool render) {
|
||||
return viewer.setRendering(render).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise render() => viewer.render().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSUint8Array> capture() {
|
||||
return viewer.capture().then((captured) => captured.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setFrameRate(int framerate) => viewer.setFrameRate(framerate).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise dispose() => viewer.dispose().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBackgroundImage(String path, {bool fillHeight = false}) =>
|
||||
viewer.setBackgroundImage(path, fillHeight: fillHeight).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBackgroundImagePosition(double x, double y,
|
||||
{bool clamp = false}) =>
|
||||
viewer.setBackgroundImagePosition(x, y, clamp: clamp).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise clearBackgroundImage() => viewer.clearBackgroundImage().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBackgroundColor(double r, double g, double b, double alpha) =>
|
||||
viewer.setBackgroundColor(r, g, b, alpha).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise loadSkybox(String skyboxPath) => viewer.loadSkybox(skyboxPath).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeSkybox() => viewer.removeSkybox().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise loadIbl(String lightingPath, double intensity) {
|
||||
_logger.info("Loading IBL from $lightingPath with intensity $intensity");
|
||||
return viewer.loadIbl(lightingPath, intensity: intensity).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateIbl(JSArray<JSNumber> rotation) {
|
||||
var matrix =
|
||||
Matrix3.fromList(rotation.toDart.map((v) => v.toDartDouble).toList());
|
||||
return viewer.rotateIbl(matrix).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeIbl() => viewer.removeIbl().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> addLight(
|
||||
int type,
|
||||
double colour,
|
||||
double intensity,
|
||||
double posX,
|
||||
double posY,
|
||||
double posZ,
|
||||
double dirX,
|
||||
double dirY,
|
||||
double dirZ,
|
||||
double falloffRadius,
|
||||
double spotLightConeInner,
|
||||
double spotLightConeOuter,
|
||||
double sunAngularRadius,
|
||||
double sunHaloSize,
|
||||
double sunHaloFallof,
|
||||
bool castShadows) {
|
||||
return viewer
|
||||
.addLight(LightType.values[type], colour, intensity, posX, posY, posZ,
|
||||
dirX, dirY, dirZ,
|
||||
falloffRadius: falloffRadius,
|
||||
spotLightConeInner: spotLightConeInner,
|
||||
spotLightConeOuter: spotLightConeOuter,
|
||||
sunAngularRadius: sunAngularRadius,
|
||||
sunHaloSize: sunHaloSize,
|
||||
sunHaloFallof: sunHaloFallof,
|
||||
castShadows: castShadows)
|
||||
.then((entity) => entity.toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeLight(ThermionEntity light) => viewer.removeLight(light).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise clearLights() => viewer.clearLights().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> loadGlb(String path, {int numInstances = 1}) {
|
||||
_logger.info("Loading GLB from path $path with numInstances $numInstances");
|
||||
return viewer
|
||||
.loadGlb(path, numInstances: numInstances)
|
||||
.then((entity) => entity.toJS)
|
||||
.catchError((err) {
|
||||
_logger.info("Error: $err");
|
||||
}).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> createInstance(ThermionEntity entity) {
|
||||
return viewer.createInstance(entity).then((instance) => instance.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getInstanceCount(ThermionEntity entity) =>
|
||||
viewer.getInstanceCount(entity).then((v) => v.toJS).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getInstances(ThermionEntity entity) {
|
||||
return viewer
|
||||
.getInstances(entity)
|
||||
.then((instances) =>
|
||||
instances.map((instance) => instance.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> loadGltf(String path, String relativeResourcePath,
|
||||
{bool keepData = false}) {
|
||||
return viewer
|
||||
.loadGltf(path, relativeResourcePath, keepData: keepData)
|
||||
.then((entity) => entity.toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise panStart(double x, double y) => viewer.panStart(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise panUpdate(double x, double y) => viewer.panUpdate(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise panEnd() => viewer.panEnd().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateStart(double x, double y) => viewer.rotateStart(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateUpdate(double x, double y) => viewer.rotateUpdate(x, y).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise rotateEnd() => viewer.rotateEnd().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMorphTargetWeights(
|
||||
ThermionEntity entity, JSArray<JSNumber> weights) {
|
||||
var dartWeights = weights.toDart.map((w) => w.toDartDouble).toList();
|
||||
return viewer.setMorphTargetWeights(entity, dartWeights).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getMorphTargetNames(
|
||||
ThermionEntity entity, ThermionEntity childEntity) {
|
||||
var morphTargetNames = viewer
|
||||
.getMorphTargetNames(entity, childEntity)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS);
|
||||
return morphTargetNames.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getBoneNames(
|
||||
ThermionEntity entity, int skinIndex) {
|
||||
return viewer
|
||||
.getBoneNames(entity, skinIndex: skinIndex)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getAnimationNames(ThermionEntity entity) =>
|
||||
viewer
|
||||
.getAnimationNames(entity)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getAnimationDuration(
|
||||
ThermionEntity entity, int animationIndex) =>
|
||||
viewer
|
||||
.getAnimationDuration(entity, animationIndex)
|
||||
.then((v) => v.toJS)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
void clearMorphAnimationData(ThermionEntity entity) {
|
||||
viewer.clearMorphAnimationData(entity);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMorphAnimationData(
|
||||
ThermionEntity entity,
|
||||
JSArray<JSArray<JSNumber>> animation,
|
||||
JSArray<JSString> morphTargets,
|
||||
JSArray<JSString>? targetMeshNames,
|
||||
double frameLengthInMs) {
|
||||
try {
|
||||
var morphTargetsDart = morphTargets.toDart.map((m) => m.toDart).toList();
|
||||
var animationDataDart = animation.toDart
|
||||
.map((x) => x.toDart.map((y) => y.toDartDouble).toList())
|
||||
.toList();
|
||||
|
||||
var morphAnimationData = MorphAnimationData(
|
||||
animationDataDart, morphTargetsDart,
|
||||
frameLengthInMs: frameLengthInMs);
|
||||
var targetMeshNamesDart =
|
||||
targetMeshNames?.toDart.map((x) => x.toDart).toList();
|
||||
if (animationDataDart.first.length != morphTargetsDart.length) {
|
||||
throw Exception(
|
||||
"Length mismatch between morph targets and animation data");
|
||||
}
|
||||
var result = viewer
|
||||
.setMorphAnimationData(
|
||||
entity,
|
||||
morphAnimationData,
|
||||
targetMeshNames: targetMeshNamesDart,
|
||||
)
|
||||
.onError((err, st) {
|
||||
_logger.severe("ERROR SETTING MORPH ANIMATION DATA : $err\n$st");
|
||||
return null;
|
||||
});
|
||||
return result.toJS;
|
||||
} catch (err, st) {
|
||||
_logger.severe(err);
|
||||
_logger.severe(st);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise resetBones(ThermionEntity entity) => viewer.resetBones(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise addBoneAnimation(
|
||||
ThermionEntity entity,
|
||||
JSArray<JSString> bones,
|
||||
JSArray<JSArray<JSArray<JSNumber>>> frameData,
|
||||
JSNumber frameLengthInMs,
|
||||
JSNumber spaceEnum,
|
||||
JSNumber skinIndex,
|
||||
JSNumber fadeInInSecs,
|
||||
JSNumber fadeOutInSecs,
|
||||
JSNumber maxDelta) {
|
||||
var frameDataDart = frameData.toDart
|
||||
.map((frame) => frame.toDart
|
||||
.map((v) {
|
||||
var values = v.toDart;
|
||||
var trans = v64.Vector3(values[0].toDartDouble,
|
||||
values[1].toDartDouble, values[2].toDartDouble);
|
||||
var rot = v64.Quaternion(
|
||||
values[3].toDartDouble,
|
||||
values[4].toDartDouble,
|
||||
values[5].toDartDouble,
|
||||
values[6].toDartDouble);
|
||||
return (rotation: rot, translation: trans);
|
||||
})
|
||||
.cast<BoneAnimationFrame>()
|
||||
.toList())
|
||||
.toList();
|
||||
|
||||
var data = BoneAnimationData(
|
||||
bones.toDart.map((n) => n.toDart).toList(), frameDataDart,
|
||||
frameLengthInMs: frameLengthInMs.toDartDouble,
|
||||
space: Space.values[spaceEnum.toDartInt]);
|
||||
|
||||
return viewer
|
||||
.addBoneAnimation(entity, data,
|
||||
skinIndex: skinIndex.toDartInt,
|
||||
fadeInInSecs: fadeInInSecs.toDartDouble,
|
||||
fadeOutInSecs: fadeOutInSecs.toDartDouble)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeEntity(ThermionEntity entity) =>
|
||||
viewer.removeEntity(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise clearEntities() {
|
||||
return viewer.clearEntities().toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise zoomBegin() => viewer.zoomBegin().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise zoomUpdate(double x, double y, double z) =>
|
||||
viewer.zoomUpdate(x, y, z).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise zoomEnd() => viewer.zoomEnd().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise playAnimation(ThermionEntity entity, int index,
|
||||
{bool loop = false,
|
||||
bool reverse = false,
|
||||
bool replaceActive = true,
|
||||
double crossfade = 0.0,
|
||||
double startOffset = 0.0}) =>
|
||||
viewer
|
||||
.playAnimation(entity, index,
|
||||
loop: loop,
|
||||
reverse: reverse,
|
||||
replaceActive: replaceActive,
|
||||
crossfade: crossfade,
|
||||
startOffset: startOffset)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise playAnimationByName(ThermionEntity entity, String name,
|
||||
{bool loop = false,
|
||||
bool reverse = false,
|
||||
bool replaceActive = true,
|
||||
double crossfade = 0.0}) =>
|
||||
viewer
|
||||
.playAnimationByName(
|
||||
entity,
|
||||
name,
|
||||
loop: loop,
|
||||
reverse: reverse,
|
||||
replaceActive: replaceActive,
|
||||
crossfade: crossfade,
|
||||
)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setAnimationFrame(
|
||||
ThermionEntity entity, int index, int animationFrame) =>
|
||||
viewer
|
||||
.setAnimationFrame(
|
||||
entity,
|
||||
index,
|
||||
animationFrame,
|
||||
)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise stopAnimation(ThermionEntity entity, int animationIndex) =>
|
||||
viewer.stopAnimation(entity, animationIndex).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise stopAnimationByName(ThermionEntity entity, String name) =>
|
||||
viewer.stopAnimationByName(entity, name).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCamera(ThermionEntity entity, String? name) =>
|
||||
viewer.setCamera(entity, name).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMainCamera() => viewer.setMainCamera().toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getMainCamera() {
|
||||
throw UnimplementedError("TODO");
|
||||
// return viewer.getMainCamera().then((camera) => camera.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setParent(
|
||||
ThermionEntity child, ThermionEntity parent, bool preserveScaling) {
|
||||
return viewer
|
||||
.setParent(child, parent, preserveScaling: preserveScaling)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraFov(double degrees, bool horizontal) =>
|
||||
viewer.setCameraFov(degrees, horizontal: horizontal).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setToneMapping(int mapper) =>
|
||||
viewer.setToneMapping(ToneMapper.values[mapper]).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBloom(double bloom) => viewer.setBloom(bloom).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraFocalLength(double focalLength) =>
|
||||
viewer.setCameraFocalLength(focalLength).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraCulling(double near, double far) =>
|
||||
viewer.setCameraCulling(near, far).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getCameraCullingNear() =>
|
||||
viewer.getCameraCullingNear().then((v) => v.toJS).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getCameraCullingFar() =>
|
||||
viewer.getCameraCullingFar().then((v) => v.toJS).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraFocusDistance(double focusDistance) =>
|
||||
viewer.setCameraFocusDistance(focusDistance).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraPosition() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraPosition().then((position) => position.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraModelMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraModelMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraViewMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraViewMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraProjectionMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraCullingProjectionMatrix() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraCullingProjectionMatrix().then((matrix) => matrix.toJSArray<JSNumber>()).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getCameraFrustum() {
|
||||
throw UnimplementedError();
|
||||
// return viewer.getCameraFrustum().then((frustum) => frustum.toJS).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraPosition(double x, double y, double z) =>
|
||||
viewer.setCameraPosition(x, y, z).toJS;
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getCameraRotation() {
|
||||
return viewer
|
||||
.getCameraRotation()
|
||||
.then((rotation) => rotation.storage.map((v) => v.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise moveCameraToAsset(ThermionEntity entity) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.moveCameraToAsset(entity)).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setViewFrustumCulling(JSBoolean enabled) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.setViewFrustumCulling(enabled).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraExposure(
|
||||
double aperture, double shutterSpeed, double sensitivity) =>
|
||||
viewer.setCameraExposure(aperture, shutterSpeed, sensitivity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraRotation(JSArray<JSNumber> quaternion) {
|
||||
var dartVals = quaternion.toDart;
|
||||
return viewer
|
||||
.setCameraRotation(v64.Quaternion(
|
||||
dartVals[0].toDartDouble,
|
||||
dartVals[1].toDartDouble,
|
||||
dartVals[2].toDartDouble,
|
||||
dartVals[3].toDartDouble))
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraModelMatrix(JSArray<JSNumber> matrix) {
|
||||
throw UnimplementedError();
|
||||
// viewer.setCameraModelMatrix(matrix).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setMaterialColor(ThermionEntity entity, String meshName,
|
||||
int materialIndex, double r, double g, double b, double a) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.setMaterialColor(
|
||||
// entity),
|
||||
// meshName,
|
||||
// materialIndex,
|
||||
// r,
|
||||
// g,
|
||||
// b,
|
||||
// a,
|
||||
// ).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise transformToUnitCube(ThermionEntity entity) =>
|
||||
viewer.transformToUnitCube(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setPosition(ThermionEntity entity, double x, double y, double z) =>
|
||||
viewer.setPosition(entity, x, y, z).toJS;
|
||||
@JSExport()
|
||||
JSPromise setScale(ThermionEntity entity, double scale) =>
|
||||
viewer.setScale(entity, scale).toJS;
|
||||
@JSExport()
|
||||
JSPromise setRotation(
|
||||
ThermionEntity entity, double rads, double x, double y, double z) =>
|
||||
viewer.setRotation(entity, rads, x, y, z).toJS;
|
||||
@JSExport()
|
||||
JSPromise queuePositionUpdate(
|
||||
ThermionEntity entity, double x, double y, double z, bool relative) =>
|
||||
viewer
|
||||
.queuePositionUpdate(
|
||||
entity,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
relative: relative,
|
||||
)
|
||||
.toJS;
|
||||
@JSExport()
|
||||
JSPromise queueRotationUpdate(ThermionEntity entity, double rads, double x,
|
||||
double y, double z, bool relative) =>
|
||||
viewer
|
||||
.queueRotationUpdate(
|
||||
entity,
|
||||
rads,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
relative: relative,
|
||||
)
|
||||
.toJS;
|
||||
@JSExport()
|
||||
JSPromise queueRotationUpdateQuat(
|
||||
ThermionEntity entity, JSArray<JSNumber> quat, JSBoolean relative) =>
|
||||
throw UnimplementedError();
|
||||
// viewer.queueRotationUpdateQuat(
|
||||
// entity,
|
||||
// quat.toDartQuaternion(),
|
||||
// relative: relative,
|
||||
// ).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setPostProcessing(bool enabled) =>
|
||||
viewer.setPostProcessing(enabled).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setAntiAliasing(bool msaa, bool fxaa, bool taa) =>
|
||||
viewer.setAntiAliasing(msaa, fxaa, taa).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRotationQuat(
|
||||
ThermionEntity entity, JSArray<JSNumber> rotation) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
@JSExport()
|
||||
JSPromise reveal(ThermionEntity entity, String? meshName) =>
|
||||
viewer.reveal(entity, meshName).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise hide(ThermionEntity entity, String? meshName) =>
|
||||
viewer.hide(entity, meshName).toJS;
|
||||
|
||||
@JSExport()
|
||||
void pick(int x, int y) => viewer.pick(x, y);
|
||||
|
||||
@JSExport()
|
||||
String? getNameForEntity(ThermionEntity entity) =>
|
||||
viewer.getNameForEntity(entity);
|
||||
|
||||
@JSExport()
|
||||
JSPromise setCameraManipulatorOptions({
|
||||
int mode = 0,
|
||||
double orbitSpeedX = 0.01,
|
||||
double orbitSpeedY = 0.01,
|
||||
double zoomSpeed = 0.01,
|
||||
}) =>
|
||||
viewer
|
||||
.setCameraManipulatorOptions(
|
||||
mode: ManipulatorMode.values[mode],
|
||||
orbitSpeedX: orbitSpeedX,
|
||||
orbitSpeedY: orbitSpeedY,
|
||||
zoomSpeed: zoomSpeed,
|
||||
)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getChildEntities(
|
||||
ThermionEntity parent, bool renderableOnly) {
|
||||
return viewer
|
||||
.getChildEntities(
|
||||
parent,
|
||||
renderableOnly,
|
||||
)
|
||||
.then((entities) => entities.map((entity) => entity.toJS).toList().toJS)
|
||||
.onError((e, st) async {
|
||||
_logger.severe("Error : $e\n$st");
|
||||
return <JSNumber>[].toJS;
|
||||
}).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSNumber> getChildEntity(ThermionEntity parent, String childName) {
|
||||
return viewer
|
||||
.getChildEntity(
|
||||
parent,
|
||||
childName,
|
||||
)
|
||||
.then((entity) => entity.toJS)
|
||||
.onError((e, st) async {
|
||||
_logger.severe("Error getChildEntity : $e\n$st");
|
||||
return 0.toJS;
|
||||
}).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSString>> getChildEntityNames(
|
||||
ThermionEntity entity, bool renderableOnly) =>
|
||||
viewer
|
||||
.getChildEntityNames(
|
||||
entity,
|
||||
renderableOnly: renderableOnly,
|
||||
)
|
||||
.then((v) => v.map((s) => s.toJS).toList().toJS)
|
||||
.toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRecording(bool recording) => viewer.setRecording(recording).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise setRecordingOutputDirectory(String outputDirectory) =>
|
||||
viewer.setRecordingOutputDirectory(outputDirectory).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise addAnimationComponent(ThermionEntity entity) =>
|
||||
viewer.addAnimationComponent(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise removeAnimationComponent(ThermionEntity entity) =>
|
||||
viewer.removeAnimationComponent(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise getParent(ThermionEntity entity) =>
|
||||
viewer.removeAnimationComponent(entity).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise getBone(ThermionEntity entity, int boneIndex, int skinIndex) =>
|
||||
viewer.getBone(entity, boneIndex, skinIndex: skinIndex).toJS;
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getLocalTransform(ThermionEntity entity) {
|
||||
return viewer
|
||||
.getLocalTransform(entity)
|
||||
.then((t) => t.storage.map((v) => v.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise<JSArray<JSNumber>> getWorldTransform(ThermionEntity entity) {
|
||||
return viewer
|
||||
.getWorldTransform(entity)
|
||||
.then((t) => t.storage.map((v) => v.toJS).toList().toJS)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setTransform(ThermionEntity entity, JSArray<JSNumber> transform) {
|
||||
return viewer
|
||||
.setTransform(
|
||||
entity,
|
||||
Matrix4.fromList(
|
||||
transform.toDart.map((v) => v.toDartDouble).toList()))
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise updateBoneMatrices(ThermionEntity entity) {
|
||||
return viewer.updateBoneMatrices(entity).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setBoneTransform(ThermionEntity entity, int boneIndex,
|
||||
JSArray<JSNumber> transform, int skinIndex) {
|
||||
return viewer
|
||||
.setBoneTransform(
|
||||
entity,
|
||||
boneIndex,
|
||||
Matrix4.fromList(
|
||||
transform.toDart.map((v) => v.toDartDouble).toList()),
|
||||
skinIndex: skinIndex)
|
||||
.toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise addCollisionComponent(ThermionEntity entity,
|
||||
{JSFunction? callback, bool affectsTransform = false}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setShadowsEnabled(bool enabled) {
|
||||
return viewer.setShadowsEnabled(enabled).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setShadowType(int shadowType) {
|
||||
return viewer.setShadowType(ShadowType.values[shadowType]).toJS;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
JSPromise setSoftShadowOptions(
|
||||
double penumbraScale, double penumbraRatioScale) {
|
||||
return viewer.setSoftShadowOptions(penumbraScale, penumbraRatioScale).toJS;
|
||||
}
|
||||
}
|
||||
1107
thermion_dart/lib/src/viewer/src/web_js/src/thermion_viewer_js.dart
Normal file
1107
thermion_dart/lib/src/viewer/src/web_js/src/thermion_viewer_js.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,424 @@
|
||||
@JS()
|
||||
library thermion_flutter_js;
|
||||
|
||||
import 'dart:js_interop';
|
||||
|
||||
import '../../shared_types/shared_types.dart';
|
||||
|
||||
///
|
||||
/// An extension type on [JSObject] that represents a
|
||||
/// Javascript shim implementation of the [ThermionViewer] interface.
|
||||
///
|
||||
extension type ThermionViewerJSShim(JSObject _) implements JSObject {
|
||||
@JS('initialized')
|
||||
external JSPromise<JSBoolean> get initialized;
|
||||
|
||||
@JS('rendering')
|
||||
external bool get rendering;
|
||||
|
||||
@JS('setRendering')
|
||||
external JSPromise setRendering(bool render);
|
||||
|
||||
@JS('render')
|
||||
external JSPromise render();
|
||||
|
||||
@JS('capture')
|
||||
external JSPromise<JSUint8Array> capture();
|
||||
|
||||
@JS('setFrameRate')
|
||||
external JSPromise setFrameRate(int framerate);
|
||||
|
||||
@JS('dispose')
|
||||
external JSPromise dispose();
|
||||
|
||||
@JS('setBackgroundImage')
|
||||
external JSPromise setBackgroundImage(String path, bool fillHeight);
|
||||
|
||||
@JS('setBackgroundImagePosition')
|
||||
external JSPromise setBackgroundImagePosition(double x, double y, bool clamp);
|
||||
|
||||
@JS('clearBackgroundImage')
|
||||
external JSPromise clearBackgroundImage();
|
||||
|
||||
@JS('setBackgroundColor')
|
||||
external JSPromise setBackgroundColor(
|
||||
double r, double g, double b, double alpha);
|
||||
|
||||
@JS('loadSkybox')
|
||||
external JSPromise loadSkybox(String skyboxPath);
|
||||
|
||||
@JS('removeSkybox')
|
||||
external JSPromise removeSkybox();
|
||||
|
||||
@JS('loadIbl')
|
||||
external JSPromise loadIbl(String lightingPath, double intensity);
|
||||
|
||||
@JS('rotateIbl')
|
||||
external JSPromise rotateIbl(JSArray<JSNumber> rotationMatrix);
|
||||
|
||||
@JS('removeIbl')
|
||||
external JSPromise removeIbl();
|
||||
|
||||
@JS('addLight')
|
||||
external JSPromise<JSNumber> addLight(
|
||||
int type,
|
||||
double colour,
|
||||
double intensity,
|
||||
double posX,
|
||||
double posY,
|
||||
double posZ,
|
||||
double dirX,
|
||||
double dirY,
|
||||
double dirZ,
|
||||
double falloffRadius,
|
||||
double spotLightConeInner,
|
||||
double spotLightConeOuter,
|
||||
double sunAngularRadius,
|
||||
double sunHaloSize,
|
||||
double sunHaloFallof,
|
||||
bool castShadows);
|
||||
|
||||
@JS('removeLight')
|
||||
external JSPromise removeLight(ThermionEntity light);
|
||||
|
||||
@JS('clearLights')
|
||||
external JSPromise clearLights();
|
||||
|
||||
@JS('loadGlb')
|
||||
external JSPromise<JSNumber> loadGlb(String path, int numInstances);
|
||||
|
||||
@JS('createInstance')
|
||||
external JSPromise<JSNumber> createInstance(ThermionEntity entity);
|
||||
|
||||
@JS('getInstanceCount')
|
||||
external JSPromise<JSNumber> getInstanceCount(ThermionEntity entity);
|
||||
|
||||
@JS('getInstances')
|
||||
external JSPromise<JSArray<JSNumber>> getInstances(ThermionEntity entity);
|
||||
|
||||
@JS('loadGltf')
|
||||
external JSPromise<JSNumber> loadGltf(
|
||||
String path, String relativeResourcePath);
|
||||
|
||||
@JS('panStart')
|
||||
external JSPromise panStart(double x, double y);
|
||||
|
||||
@JS('panUpdate')
|
||||
external JSPromise panUpdate(double x, double y);
|
||||
|
||||
@JS('panEnd')
|
||||
external JSPromise panEnd();
|
||||
|
||||
@JS('rotateStart')
|
||||
external JSPromise rotateStart(double x, double y);
|
||||
|
||||
@JS('rotateUpdate')
|
||||
external JSPromise rotateUpdate(double x, double y);
|
||||
|
||||
@JS('rotateEnd')
|
||||
external JSPromise rotateEnd();
|
||||
|
||||
@JS('setMorphTargetWeights')
|
||||
external JSPromise setMorphTargetWeights(
|
||||
ThermionEntity entity, JSArray<JSNumber> weights);
|
||||
|
||||
@JS('getMorphTargetNames')
|
||||
external JSPromise<JSArray<JSString>> getMorphTargetNames(
|
||||
ThermionEntity entity, ThermionEntity childEntity);
|
||||
|
||||
@JS('getBoneNames')
|
||||
external JSPromise<JSArray<JSString>> getBoneNames(
|
||||
ThermionEntity entity, int skinIndex);
|
||||
|
||||
@JS('getAnimationNames')
|
||||
external JSPromise<JSArray<JSString>> getAnimationNames(
|
||||
ThermionEntity entity);
|
||||
|
||||
@JS('getAnimationDuration')
|
||||
external JSPromise<JSNumber> getAnimationDuration(
|
||||
ThermionEntity entity, int animationIndex);
|
||||
|
||||
@JS('clearMorphAnimationData')
|
||||
external void clearMorphAnimationData(ThermionEntity entity);
|
||||
|
||||
@JS('setMorphAnimationData')
|
||||
external JSPromise setMorphAnimationData(
|
||||
ThermionEntity entity,
|
||||
JSArray<JSArray<JSNumber>> animation,
|
||||
JSArray<JSString> morphTargets,
|
||||
JSArray<JSString>? targetMeshNames,
|
||||
double frameLengthInMs);
|
||||
|
||||
@JS('resetBones')
|
||||
external JSPromise resetBones(ThermionEntity entity);
|
||||
|
||||
@JS('addBoneAnimation')
|
||||
external JSPromise addBoneAnimation(
|
||||
ThermionEntity entity,
|
||||
JSArray<JSString> bones,
|
||||
JSArray<JSArray<JSArray<JSNumber>>> frameData,
|
||||
JSNumber frameLengthInMs,
|
||||
JSNumber spaceEnum,
|
||||
JSNumber skinIndex,
|
||||
JSNumber fadeInInSecs,
|
||||
JSNumber fadeOutInSecs,
|
||||
JSNumber maxDelta);
|
||||
|
||||
@JS('removeEntity')
|
||||
external JSPromise removeEntity(ThermionEntity entity);
|
||||
|
||||
@JS('clearEntities')
|
||||
external JSPromise clearEntities();
|
||||
|
||||
@JS('zoomBegin')
|
||||
external JSPromise zoomBegin();
|
||||
|
||||
@JS('zoomUpdate')
|
||||
external JSPromise zoomUpdate(double x, double y, double z);
|
||||
|
||||
@JS('zoomEnd')
|
||||
external JSPromise zoomEnd();
|
||||
|
||||
@JS('playAnimation')
|
||||
external JSPromise playAnimation(
|
||||
ThermionEntity entity,
|
||||
int index,
|
||||
bool loop,
|
||||
bool reverse,
|
||||
bool replaceActive,
|
||||
double crossfade,
|
||||
double startOffset,
|
||||
);
|
||||
|
||||
@JS('playAnimationByName')
|
||||
external JSPromise playAnimationByName(
|
||||
ThermionEntity entity,
|
||||
String name,
|
||||
bool loop,
|
||||
bool reverse,
|
||||
bool replaceActive,
|
||||
double crossfade,
|
||||
);
|
||||
|
||||
@JS('setAnimationFrame')
|
||||
external JSPromise setAnimationFrame(
|
||||
ThermionEntity entity, int index, int animationFrame);
|
||||
|
||||
@JS('stopAnimation')
|
||||
external JSPromise stopAnimation(ThermionEntity entity, int animationIndex);
|
||||
|
||||
@JS('stopAnimationByName')
|
||||
external JSPromise stopAnimationByName(ThermionEntity entity, String name);
|
||||
|
||||
@JS('setCamera')
|
||||
external JSPromise setCamera(ThermionEntity entity, String? name);
|
||||
|
||||
@JS('setMainCamera')
|
||||
external JSPromise setMainCamera();
|
||||
|
||||
@JS('getMainCamera')
|
||||
external JSPromise<JSNumber> getMainCamera();
|
||||
|
||||
@JS('setCameraFov')
|
||||
external JSPromise setCameraFov(double degrees, bool horizontal);
|
||||
|
||||
@JS('setToneMapping')
|
||||
external JSPromise setToneMapping(int mapper);
|
||||
|
||||
@JS('setBloom')
|
||||
external JSPromise setBloom(double bloom);
|
||||
|
||||
@JS('setCameraFocalLength')
|
||||
external JSPromise setCameraFocalLength(double focalLength);
|
||||
|
||||
@JS('setCameraCulling')
|
||||
external JSPromise setCameraCulling(double near, double far);
|
||||
|
||||
@JS('getCameraCullingNear')
|
||||
external JSPromise<JSNumber> getCameraCullingNear();
|
||||
|
||||
@JS('getCameraCullingFar')
|
||||
external JSPromise<JSNumber> getCameraCullingFar();
|
||||
|
||||
@JS('setCameraFocusDistance')
|
||||
external JSPromise setCameraFocusDistance(double focusDistance);
|
||||
|
||||
@JS('getCameraPosition')
|
||||
external JSPromise<JSArray<JSNumber>> getCameraPosition();
|
||||
|
||||
@JS('getCameraModelMatrix')
|
||||
external JSPromise<JSArray<JSNumber>> getCameraModelMatrix();
|
||||
|
||||
@JS('getCameraViewMatrix')
|
||||
external JSPromise<JSArray<JSNumber>> getCameraViewMatrix();
|
||||
|
||||
@JS('getCameraProjectionMatrix')
|
||||
external JSPromise<JSArray<JSNumber>> getCameraProjectionMatrix();
|
||||
|
||||
@JS('getCameraCullingProjectionMatrix')
|
||||
external JSPromise<JSArray<JSNumber>> getCameraCullingProjectionMatrix();
|
||||
|
||||
@JS('getCameraFrustum')
|
||||
external JSPromise<JSObject> getCameraFrustum();
|
||||
|
||||
@JS('setCameraPosition')
|
||||
external JSPromise setCameraPosition(double x, double y, double z);
|
||||
|
||||
@JS('getCameraRotation')
|
||||
external JSPromise<JSArray<JSNumber>> getCameraRotation();
|
||||
|
||||
@JS('moveCameraToAsset')
|
||||
external JSPromise moveCameraToAsset(ThermionEntity entity);
|
||||
|
||||
@JS('setViewFrustumCulling')
|
||||
external JSPromise setViewFrustumCulling(JSBoolean enabled);
|
||||
|
||||
@JS('setCameraExposure')
|
||||
external JSPromise setCameraExposure(
|
||||
double aperture, double shutterSpeed, double sensitivity);
|
||||
|
||||
@JS('setCameraRotation')
|
||||
external JSPromise setCameraRotation(JSArray<JSNumber> quaternion);
|
||||
|
||||
@JS('setCameraModelMatrix')
|
||||
external JSPromise setCameraModelMatrix(JSArray<JSNumber> matrix);
|
||||
|
||||
@JS('setMaterialColor')
|
||||
external JSPromise setMaterialColor(ThermionEntity entity, String meshName,
|
||||
int materialIndex, double r, double g, double b, double a);
|
||||
|
||||
@JS('transformToUnitCube')
|
||||
external JSPromise transformToUnitCube(ThermionEntity entity);
|
||||
|
||||
@JS('setPosition')
|
||||
external JSPromise setPosition(
|
||||
ThermionEntity entity, double x, double y, double z);
|
||||
|
||||
@JS('setScale')
|
||||
external JSPromise setScale(ThermionEntity entity, double scale);
|
||||
|
||||
@JS('setRotation')
|
||||
external JSPromise setRotation(
|
||||
ThermionEntity entity, double rads, double x, double y, double z);
|
||||
|
||||
@JS('queuePositionUpdate')
|
||||
external JSPromise queuePositionUpdate(
|
||||
ThermionEntity entity, double x, double y, double z, bool relative);
|
||||
|
||||
@JS('queueRotationUpdate')
|
||||
external JSPromise queueRotationUpdate(ThermionEntity entity, double rads,
|
||||
double x, double y, double z, bool relative);
|
||||
|
||||
@JS('queueRotationUpdateQuat')
|
||||
external JSPromise queueRotationUpdateQuat(
|
||||
ThermionEntity entity, JSArray<JSNumber> quat, bool relative);
|
||||
|
||||
@JS('setPostProcessing')
|
||||
external JSPromise setPostProcessing(bool enabled);
|
||||
|
||||
@JS('setAntiAliasing')
|
||||
external JSPromise setAntiAliasing(bool msaa, bool fxaa, bool taa);
|
||||
|
||||
@JS('setRotationQuat')
|
||||
external JSPromise setRotationQuat(
|
||||
ThermionEntity entity, JSArray<JSNumber> rotation);
|
||||
|
||||
@JS('reveal')
|
||||
external JSPromise reveal(ThermionEntity entity, String? meshName);
|
||||
|
||||
@JS('hide')
|
||||
external JSPromise hide(ThermionEntity entity, String? meshName);
|
||||
|
||||
@JS('pick')
|
||||
external void pick(int x, int y);
|
||||
|
||||
@JS('getNameForEntity')
|
||||
external String? getNameForEntity(ThermionEntity entity);
|
||||
|
||||
@JS('setCameraManipulatorOptions')
|
||||
external JSPromise setCameraManipulatorOptions(
|
||||
int mode,
|
||||
double orbitSpeedX,
|
||||
double orbitSpeedY,
|
||||
double zoomSpeed,
|
||||
);
|
||||
|
||||
@JS('getChildEntities')
|
||||
external JSPromise<JSArray<JSNumber>> getChildEntities(
|
||||
ThermionEntity parent, bool renderableOnly);
|
||||
|
||||
@JS('getChildEntity')
|
||||
external JSPromise<JSNumber> getChildEntity(
|
||||
ThermionEntity parent, String childName);
|
||||
|
||||
@JS('getChildEntityNames')
|
||||
external JSPromise<JSArray<JSString>> getChildEntityNames(
|
||||
ThermionEntity entity, bool renderableOnly);
|
||||
|
||||
@JS('setRecording')
|
||||
external JSPromise setRecording(JSBoolean recording);
|
||||
|
||||
@JS('setRecordingOutputDirectory')
|
||||
external JSPromise setRecordingOutputDirectory(String outputDirectory);
|
||||
|
||||
@JS('addAnimationComponent')
|
||||
external JSPromise addAnimationComponent(ThermionEntity entity);
|
||||
|
||||
@JS('removeAnimationComponent')
|
||||
external JSPromise removeAnimationComponent(ThermionEntity entity);
|
||||
|
||||
@JS('addCollisionComponent')
|
||||
external JSPromise addCollisionComponent(ThermionEntity entity);
|
||||
|
||||
@JS('removeCollisionComponent')
|
||||
external JSPromise removeCollisionComponent(ThermionEntity entity);
|
||||
|
||||
@JS('createGeometry')
|
||||
external JSPromise<JSNumber> createGeometry(JSArray<JSNumber> vertices,
|
||||
JSArray<JSNumber> indices, String? materialPath, int primitiveType);
|
||||
|
||||
@JS('setParent')
|
||||
external JSPromise setParent(ThermionEntity child, ThermionEntity parent, bool preserveScaling);
|
||||
|
||||
@JS('getParent')
|
||||
external JSPromise<JSNumber> getParent(ThermionEntity child);
|
||||
|
||||
@JS('getParent')
|
||||
external JSPromise<JSNumber> getBone(
|
||||
ThermionEntity child, int boneIndex, int skinIndex);
|
||||
|
||||
@JS('testCollisions')
|
||||
external JSPromise testCollisions(ThermionEntity entity);
|
||||
|
||||
@JS('setPriority')
|
||||
external JSPromise setPriority(ThermionEntity entityId, int priority);
|
||||
|
||||
@JS('getLocalTransform')
|
||||
external JSPromise<JSArray<JSNumber>> getLocalTransform(
|
||||
ThermionEntity entity);
|
||||
|
||||
@JS('getWorldTransform')
|
||||
external JSPromise<JSArray<JSNumber>> getWorldTransform(
|
||||
ThermionEntity entity);
|
||||
|
||||
@JS('updateBoneMatrices')
|
||||
external JSPromise updateBoneMatrices(ThermionEntity entity);
|
||||
|
||||
@JS('setTransform')
|
||||
external JSPromise setTransform(
|
||||
ThermionEntity entity, JSArray<JSNumber> transform);
|
||||
|
||||
@JS('setBoneTransform')
|
||||
external JSPromise setBoneTransform(ThermionEntity entity, int boneIndex,
|
||||
JSArray<JSNumber> transform, int skinIndex);
|
||||
|
||||
@JS('setShadowsEnabled')
|
||||
external JSPromise setShadowsEnabled(bool enabled);
|
||||
|
||||
@JS('setShadowType')
|
||||
external JSPromise setShadowType(int shadowType);
|
||||
|
||||
@JS('setSoftShadowOptions')
|
||||
external JSPromise setSoftShadowOptions(
|
||||
double penumbraScale, double penumbraRatioScale);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
library;
|
||||
|
||||
export 'src/thermion_viewer_dart_bridge.dart';
|
||||
export 'src/thermion_viewer_js_shim.dart';
|
||||
export 'src/thermion_viewer_js.dart';
|
||||
48
thermion_dart/lib/src/viewer/src/web_wasm/src/camera.dart
Normal file
48
thermion_dart/lib/src/viewer/src/web_wasm/src/camera.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../shared_types/camera.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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import '../../../viewer.dart';
|
||||
|
||||
class ThermionWasmMaterialInstance extends MaterialInstance {
|
||||
final int pointer;
|
||||
|
||||
ThermionWasmMaterialInstance(this.pointer);
|
||||
@override
|
||||
Future setDepthCullingEnabled(bool enabled) {
|
||||
// TODO: implement setDepthCullingEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthWriteEnabled(bool enabled) {
|
||||
// TODO: implement setDepthWriteEnabled
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
library;
|
||||
|
||||
export 'src/thermion_viewer_wasm.dart' show ThermionViewerWasm;
|
||||
7
thermion_dart/lib/src/viewer/viewer.dart
Normal file
7
thermion_dart/lib/src/viewer/viewer.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
library thermion_viewer;
|
||||
|
||||
export 'src/shared_types/shared_types.dart';
|
||||
export 'src/thermion_viewer_base.dart';
|
||||
export 'src/thermion_viewer_stub.dart'
|
||||
if (dart.library.io) 'src/ffi/thermion_viewer_ffi.dart'
|
||||
if (dart.library.js_interop) 'src/web_wasm/thermion_viewer_web_wasm.dart';
|
||||
Reference in New Issue
Block a user