fix morph animations
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import 'package:polyvox_filament/animations/animations.dart';
|
||||
import 'package:polyvox_filament/filament_controller.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:vector_math/vector_math.dart';
|
||||
|
||||
class AnimationBuilder {
|
||||
final FilamentController controller;
|
||||
DartBoneAnimation? dartBoneAnimation;
|
||||
double _frameLengthInMs = 0;
|
||||
double _duration = 0;
|
||||
int _numMorphWeights = 0;
|
||||
|
||||
double? _interpMorphStart;
|
||||
double? _interpMorphEnd;
|
||||
@@ -17,14 +18,26 @@ class AnimationBuilder {
|
||||
|
||||
List<DartBoneAnimation>? _dartBoneAnimations = null;
|
||||
|
||||
Tuple2<MorphAnimation, List<DartBoneAnimation>> build(
|
||||
String meshName, List<String> morphNames) {
|
||||
if (_numMorphWeights == 0 || _duration == 0 || _frameLengthInMs == 0)
|
||||
FilamentEntity asset;
|
||||
String meshName;
|
||||
late List<String> morphNames;
|
||||
|
||||
AnimationBuilder(
|
||||
{required this.controller,
|
||||
required this.asset,
|
||||
required this.meshName,
|
||||
required int framerate}) {
|
||||
_frameLengthInMs = 1000 / framerate;
|
||||
morphNames = controller.getMorphTargetNames(asset, meshName);
|
||||
}
|
||||
|
||||
void set() {
|
||||
if (morphNames.isEmpty == 0 || _duration == 0 || _frameLengthInMs == 0)
|
||||
throw Exception();
|
||||
|
||||
int numFrames = _duration * 1000 ~/ _frameLengthInMs;
|
||||
|
||||
final morphData = Float32List((numFrames * _numMorphWeights).toInt());
|
||||
final morphData = Float32List((numFrames * morphNames.length).toInt());
|
||||
|
||||
var frameStart = (_interpMorphStart! * 1000) ~/ _frameLengthInMs;
|
||||
var frameEnd = (_interpMorphEnd! * 1000) ~/ _frameLengthInMs;
|
||||
@@ -34,21 +47,17 @@ class AnimationBuilder {
|
||||
|
||||
var val = ((1 - linear) * _interpMorphStartValue!) +
|
||||
(linear * _interpMorphEndValue!);
|
||||
for (int j = 0; j < _numMorphWeights; j++) {
|
||||
morphData[(i * _numMorphWeights) + j] = val;
|
||||
for (int j = 0; j < morphNames.length; j++) {
|
||||
morphData[(i * morphNames.length) + j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
var morphAnimation =
|
||||
MorphAnimation(meshName, morphData, morphNames, _frameLengthInMs);
|
||||
|
||||
return Tuple2<MorphAnimation, List<DartBoneAnimation>>(
|
||||
morphAnimation, _dartBoneAnimations!);
|
||||
}
|
||||
|
||||
AnimationBuilder setFramerate(int framerate) {
|
||||
_frameLengthInMs = 1000 / framerate;
|
||||
return this;
|
||||
print("SETTING!");
|
||||
controller.setMorphAnimation(asset, morphAnimation);
|
||||
// return Tuple2<MorphAnimation, List<DartBoneAnimation>>(
|
||||
// morphAnimation, _dartBoneAnimations!);
|
||||
}
|
||||
|
||||
AnimationBuilder setDuration(double secs) {
|
||||
@@ -56,11 +65,6 @@ class AnimationBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
AnimationBuilder setNumMorphWeights(int numMorphWeights) {
|
||||
_numMorphWeights = numMorphWeights;
|
||||
return this;
|
||||
}
|
||||
|
||||
AnimationBuilder interpolateMorphWeights(
|
||||
double start, double end, double startValue, double endValue) {
|
||||
this._interpMorphStart = start;
|
||||
|
||||
@@ -24,7 +24,9 @@ class MorphAnimation {
|
||||
final Float32List data;
|
||||
|
||||
MorphAnimation(
|
||||
this.meshName, this.data, this.morphNames, this.frameLengthInMs);
|
||||
this.meshName, this.data, this.morphNames, this.frameLengthInMs) {
|
||||
assert(data.length == morphNames.length * numFrames);
|
||||
}
|
||||
|
||||
int get numMorphWeights => morphNames.length;
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ class FilamentController {
|
||||
|
||||
bool _rendering = false;
|
||||
|
||||
final _port = ReceivePort();
|
||||
final TickerProvider _tickerProvider;
|
||||
Ticker? _ticker;
|
||||
|
||||
///
|
||||
/// This now uses an FFI implementation.
|
||||
@@ -49,7 +50,7 @@ class FilamentController {
|
||||
/// All other methods directly invoke the FFI functions defined in PolyvoxFilamentApi.cpp,
|
||||
/// which itself uses a threadpool so that calls are run on a separate thread.
|
||||
///
|
||||
FilamentController() {
|
||||
FilamentController(this._tickerProvider) {
|
||||
_channel.setMethodCallHandler((call) async {
|
||||
throw Exception("Unknown method channel invocation ${call.method}");
|
||||
});
|
||||
@@ -75,7 +76,6 @@ class FilamentController {
|
||||
|
||||
void render() {
|
||||
_nativeLibrary.render(_viewer, 0);
|
||||
_channel.invokeMethod("onFrameAvailable");
|
||||
}
|
||||
|
||||
Future setFrameRate(int framerate) async {
|
||||
@@ -87,12 +87,6 @@ class FilamentController {
|
||||
}
|
||||
|
||||
Future createViewer(int width, int height) async {
|
||||
// if (_viewer.address == 0) {
|
||||
// throw Exception("TODO");
|
||||
// }
|
||||
_nativeLibrary.init_dart_api_dl(NativeApi.initializeApiDLData);
|
||||
_nativeLibrary.register_filament_port(_port.sendPort.nativePort);
|
||||
|
||||
size = ui.Size(width * _pixelRatio, height * _pixelRatio);
|
||||
_textureId =
|
||||
await _channel.invokeMethod("createTexture", [size.width, size.height]);
|
||||
@@ -123,17 +117,32 @@ class FilamentController {
|
||||
_initialized.complete(true);
|
||||
_assetManager = _nativeLibrary.get_asset_manager(_viewer);
|
||||
|
||||
await _channel.invokeMethod("setRenderTicker", _viewer.address);
|
||||
// await _channel.invokeMethod("setRenderTicker", _viewer.address);
|
||||
|
||||
_ticker = _tickerProvider.createTicker((elapsed) async {
|
||||
_nativeLibrary.render(_viewer, 0);
|
||||
await _channel.invokeMethod("tick");
|
||||
});
|
||||
_ticker!.start();
|
||||
}
|
||||
|
||||
Future resize(int width, int height,
|
||||
{double contentScaleFactor = 1.0}) async {
|
||||
size = ui.Size(width * _pixelRatio, height * _pixelRatio);
|
||||
// await setRendering(false);
|
||||
// _textureIdController.add(null);
|
||||
// _nativeLibrary.destroy_swap_chain(_viewer);
|
||||
// size = ui.Size(width * _pixelRatio, height * _pixelRatio);
|
||||
|
||||
_textureId = await _channel.invokeMethod("resize",
|
||||
[width * _pixelRatio, height * _pixelRatio, contentScaleFactor]);
|
||||
// _textureId = await _channel.invokeMethod("resize",
|
||||
// [width * _pixelRatio, height * _pixelRatio, contentScaleFactor]);
|
||||
|
||||
_textureIdController.add(_textureId);
|
||||
// _textureIdController.add(_textureId);
|
||||
// _nativeLibrary.create_swap_chain(_viewer, nullptr, width, height);
|
||||
// _nativeLibrary.create_render_target(
|
||||
// _viewer, await _channel.invokeMethod("getGlTextureId"), width, height);
|
||||
// _nativeLibrary.update_viewport_and_camera_projection(
|
||||
// _viewer, width, height, contentScaleFactor);
|
||||
// await setRendering(true);
|
||||
}
|
||||
|
||||
void clearBackgroundImage() async {
|
||||
@@ -362,6 +371,7 @@ class FilamentController {
|
||||
|
||||
void playAnimation(FilamentEntity asset, int index,
|
||||
{bool loop = false, bool reverse = false}) async {
|
||||
print("LOOP $loop");
|
||||
_nativeLibrary.play_animation(
|
||||
_assetManager, asset, index, loop ? 1 : 0, reverse ? 1 : 0);
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@ class _FilamentWidgetState extends State<FilamentWidget> {
|
||||
width: constraints.maxWidth,
|
||||
child: ResizeObserver(
|
||||
onResized: (Size oldSize, Size newSize) async {
|
||||
setState(() {
|
||||
_resizing = true;
|
||||
});
|
||||
// setState(() {
|
||||
// _resizing = true;
|
||||
// });
|
||||
|
||||
await widget.controller.resize(
|
||||
newSize.width.toInt(), newSize.height.toInt());
|
||||
|
||||
@@ -33,20 +33,6 @@ class NativeLibrary {
|
||||
late final _init_dart_api_dl =
|
||||
_init_dart_api_dlPtr.asFunction<int Function(ffi.Pointer<ffi.Void>)>();
|
||||
|
||||
void register_filament_port(
|
||||
int port,
|
||||
) {
|
||||
return _register_filament_port(
|
||||
port,
|
||||
);
|
||||
}
|
||||
|
||||
late final _register_filament_portPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>(
|
||||
'register_filament_port');
|
||||
late final _register_filament_port =
|
||||
_register_filament_portPtr.asFunction<void Function(int)>();
|
||||
|
||||
ffi.Pointer<ffi.Void> create_filament_viewer(
|
||||
ffi.Pointer<ffi.Void> context,
|
||||
ffi.Pointer<
|
||||
@@ -79,16 +65,6 @@ class NativeLibrary {
|
||||
ResourceBuffer Function(ffi.Pointer<ffi.Char>)>>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Uint32)>>)>();
|
||||
|
||||
renderCallback make_render_callback() {
|
||||
return _make_render_callback();
|
||||
}
|
||||
|
||||
late final _make_render_callbackPtr =
|
||||
_lookup<ffi.NativeFunction<renderCallback Function()>>(
|
||||
'make_render_callback');
|
||||
late final _make_render_callback =
|
||||
_make_render_callbackPtr.asFunction<renderCallback Function()>();
|
||||
|
||||
void delete_filament_viewer(
|
||||
ffi.Pointer<ffi.Void> viewer,
|
||||
) {
|
||||
@@ -648,7 +624,7 @@ class NativeLibrary {
|
||||
void Function(ffi.Pointer<ffi.Void>, int, ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.Float>, int)>();
|
||||
|
||||
void set_morph_animation(
|
||||
int set_morph_animation(
|
||||
ffi.Pointer<ffi.Void> assetManager,
|
||||
int asset,
|
||||
ffi.Pointer<ffi.Char> entityName,
|
||||
@@ -670,7 +646,7 @@ class NativeLibrary {
|
||||
|
||||
late final _set_morph_animationPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int Function(
|
||||
ffi.Pointer<ffi.Void>,
|
||||
EntityId,
|
||||
ffi.Pointer<ffi.Char>,
|
||||
@@ -679,7 +655,7 @@ class NativeLibrary {
|
||||
ffi.Int,
|
||||
ffi.Float)>>('set_morph_animation');
|
||||
late final _set_morph_animation = _set_morph_animationPtr.asFunction<
|
||||
void Function(ffi.Pointer<ffi.Void>, int, ffi.Pointer<ffi.Char>,
|
||||
int Function(ffi.Pointer<ffi.Void>, int, ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.Float>, int, int, double)>();
|
||||
|
||||
void set_bone_animation(
|
||||
@@ -1159,8 +1135,6 @@ class ResourceBuffer extends ffi.Struct {
|
||||
external int id;
|
||||
}
|
||||
|
||||
typedef renderCallback = ffi.Pointer<
|
||||
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> viewer)>>;
|
||||
typedef EntityId = ffi.Int32;
|
||||
|
||||
const int _STDINT_H = 1;
|
||||
|
||||
Reference in New Issue
Block a user