fix morph animations

This commit is contained in:
Nick Fisher
2023-04-20 15:45:59 +08:00
parent e0d3aba6d8
commit 7225cb53b1
12 changed files with 366 additions and 438 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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;