allow partial morph animations
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import 'package:polyvox_filament/animations/bone_animation_data.dart';
|
||||
import 'package:polyvox_filament/animations/morph_animation_data.dart';
|
||||
import 'package:polyvox_filament/filament_controller.dart';
|
||||
|
||||
@@ -6,7 +5,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:vector_math/vector_math.dart';
|
||||
|
||||
class AnimationBuilder {
|
||||
final FilamentController controller;
|
||||
// BoneAnimationData? BoneAnimationData;
|
||||
double _frameLengthInMs = 0;
|
||||
double _duration = 0;
|
||||
@@ -18,28 +16,25 @@ class AnimationBuilder {
|
||||
|
||||
// List<BoneAnimationData>? _BoneAnimationDatas = null;
|
||||
|
||||
FilamentEntity asset;
|
||||
String meshName;
|
||||
late List<String> morphNames;
|
||||
late List<String> availableMorphs;
|
||||
late List<int> _morphTargets;
|
||||
|
||||
AnimationBuilder(
|
||||
{required this.controller,
|
||||
required this.asset,
|
||||
{required this.availableMorphs,
|
||||
required this.meshName,
|
||||
required int framerate}) {
|
||||
_frameLengthInMs = 1000 / framerate;
|
||||
controller.getMorphTargetNames(asset, meshName).then((value) {
|
||||
morphNames = value;
|
||||
});
|
||||
}
|
||||
|
||||
void set() {
|
||||
if (morphNames.isEmpty == 0 || _duration == 0 || _frameLengthInMs == 0)
|
||||
MorphAnimationData build() {
|
||||
if (availableMorphs.isEmpty == 0 || _duration == 0 || _frameLengthInMs == 0)
|
||||
throw Exception();
|
||||
|
||||
int numFrames = _duration * 1000 ~/ _frameLengthInMs;
|
||||
|
||||
final morphData = Float32List((numFrames * morphNames.length).toInt());
|
||||
final morphData =
|
||||
List<double>.filled((numFrames * _morphTargets.length).toInt(), 0.0);
|
||||
|
||||
var frameStart = (_interpMorphStart! * 1000) ~/ _frameLengthInMs;
|
||||
var frameEnd = (_interpMorphEnd! * 1000) ~/ _frameLengthInMs;
|
||||
@@ -49,17 +44,16 @@ class AnimationBuilder {
|
||||
|
||||
var val = ((1 - linear) * _interpMorphStartValue!) +
|
||||
(linear * _interpMorphEndValue!);
|
||||
for (int j = 0; j < morphNames.length; j++) {
|
||||
morphData[(i * morphNames.length) + j] = val;
|
||||
for (int j = 0; j < _morphTargets.length; j++) {
|
||||
morphData[(i * _morphTargets.length) + j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
var morphAnimation =
|
||||
MorphAnimationData(meshName, morphData, morphNames, _frameLengthInMs);
|
||||
|
||||
controller.setMorphAnimationData(asset, morphAnimation);
|
||||
// return Tuple2<MorphAnimationData, List<BoneAnimationData>>(
|
||||
// morphAnimation, _BoneAnimationDatas!);
|
||||
return MorphAnimationData(
|
||||
meshName,
|
||||
morphData,
|
||||
_morphTargets.map((i) => availableMorphs[i]).toList(),
|
||||
_morphTargets,
|
||||
_frameLengthInMs);
|
||||
}
|
||||
|
||||
AnimationBuilder setDuration(double secs) {
|
||||
@@ -67,6 +61,11 @@ class AnimationBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
AnimationBuilder setMorphTargets(List<String> names) {
|
||||
_morphTargets = names.map((name) => availableMorphs.indexOf(name)).toList();
|
||||
return this;
|
||||
}
|
||||
|
||||
AnimationBuilder interpolateMorphWeights(
|
||||
double start, double end, double startValue, double endValue) {
|
||||
this._interpMorphStart = start;
|
||||
|
||||
@@ -32,7 +32,11 @@ class DynamicAnimation {
|
||||
}
|
||||
|
||||
var morphAnimationData = MorphAnimationData(
|
||||
meshName ?? "NULL", llf.item2, morphNames, frameLengthInMs);
|
||||
meshName ?? "NULL",
|
||||
llf.item2,
|
||||
morphNames,
|
||||
List<int>.generate(morphNames.length, (index) => index),
|
||||
frameLengthInMs);
|
||||
|
||||
final boneAnimations = <BoneAnimationData>[];
|
||||
|
||||
|
||||
@@ -9,24 +9,25 @@ import 'dart:typed_data';
|
||||
class MorphAnimationData {
|
||||
final String meshName;
|
||||
final List<String> morphNames;
|
||||
final List<int> morphIndices;
|
||||
|
||||
final Float32List data;
|
||||
final List<double> data;
|
||||
|
||||
MorphAnimationData(
|
||||
this.meshName, this.data, this.morphNames, this.frameLengthInMs) {
|
||||
MorphAnimationData(this.meshName, this.data, this.morphNames,
|
||||
this.morphIndices, this.frameLengthInMs) {
|
||||
assert(data.length == morphNames.length * numFrames);
|
||||
}
|
||||
|
||||
int get numMorphWeights => morphNames.length;
|
||||
int get numMorphTargets => morphNames.length;
|
||||
|
||||
int get numFrames => data.length ~/ numMorphWeights;
|
||||
int get numFrames => data.length ~/ numMorphTargets;
|
||||
|
||||
final double frameLengthInMs;
|
||||
|
||||
Iterable<double> getData(String morphName) sync* {
|
||||
int index = morphNames.indexOf(morphName);
|
||||
for (int i = 0; i < numFrames; i++) {
|
||||
yield data[(i * numMorphWeights) + index];
|
||||
yield data[(i * numMorphTargets) + index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,12 +260,14 @@ class FilamentController {
|
||||
///
|
||||
void setMorphAnimationData(
|
||||
FilamentEntity asset, MorphAnimationData animation) async {
|
||||
print("SETTING animation with ${animation.data}");
|
||||
await _channel.invokeMethod("setMorphAnimation", [
|
||||
_assetManager,
|
||||
asset,
|
||||
animation.meshName,
|
||||
animation.data,
|
||||
animation.numMorphWeights,
|
||||
animation.morphIndices,
|
||||
animation.numMorphTargets,
|
||||
animation.numFrames,
|
||||
animation.frameLengthInMs
|
||||
]);
|
||||
|
||||
@@ -450,21 +450,6 @@ class NativeLibrary {
|
||||
late final _set_frame_interval = _set_frame_intervalPtr
|
||||
.asFunction<void Function(ffi.Pointer<ffi.Void>, double)>();
|
||||
|
||||
ffi.Pointer<ffi.Void> get_renderer(
|
||||
ffi.Pointer<ffi.Void> viewer,
|
||||
) {
|
||||
return _get_renderer(
|
||||
viewer,
|
||||
);
|
||||
}
|
||||
|
||||
late final _get_rendererPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Pointer<ffi.Void> Function(
|
||||
ffi.Pointer<ffi.Void>)>>('get_renderer');
|
||||
late final _get_renderer = _get_rendererPtr
|
||||
.asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
|
||||
|
||||
void update_viewport_and_camera_projection(
|
||||
ffi.Pointer<ffi.Void> viewer,
|
||||
int width,
|
||||
@@ -652,7 +637,8 @@ class NativeLibrary {
|
||||
int asset,
|
||||
ffi.Pointer<ffi.Char> entityName,
|
||||
ffi.Pointer<ffi.Float> morphData,
|
||||
int numMorphWeights,
|
||||
ffi.Pointer<ffi.Int> morphIndices,
|
||||
int numMorphTargets,
|
||||
int numFrames,
|
||||
double frameLengthInMs,
|
||||
) {
|
||||
@@ -661,7 +647,8 @@ class NativeLibrary {
|
||||
asset,
|
||||
entityName,
|
||||
morphData,
|
||||
numMorphWeights,
|
||||
morphIndices,
|
||||
numMorphTargets,
|
||||
numFrames,
|
||||
frameLengthInMs,
|
||||
);
|
||||
@@ -674,12 +661,13 @@ class NativeLibrary {
|
||||
EntityId,
|
||||
ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.Float>,
|
||||
ffi.Pointer<ffi.Int>,
|
||||
ffi.Int,
|
||||
ffi.Int,
|
||||
ffi.Float)>>('set_morph_animation');
|
||||
late final _set_morph_animation = _set_morph_animationPtr.asFunction<
|
||||
int Function(ffi.Pointer<ffi.Void>, int, ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.Float>, int, int, double)>();
|
||||
ffi.Pointer<ffi.Float>, ffi.Pointer<ffi.Int>, int, int, double)>();
|
||||
|
||||
void set_bone_animation(
|
||||
ffi.Pointer<ffi.Void> assetManager,
|
||||
@@ -735,6 +723,7 @@ class NativeLibrary {
|
||||
int index,
|
||||
int loop,
|
||||
int reverse,
|
||||
int replaceActive,
|
||||
double crossfade,
|
||||
) {
|
||||
return _play_animation(
|
||||
@@ -743,6 +732,7 @@ class NativeLibrary {
|
||||
index,
|
||||
loop,
|
||||
reverse,
|
||||
replaceActive,
|
||||
crossfade,
|
||||
);
|
||||
}
|
||||
@@ -750,9 +740,9 @@ class NativeLibrary {
|
||||
late final _play_animationPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int,
|
||||
ffi.Int, ffi.Float)>>('play_animation');
|
||||
ffi.Int, ffi.Int, ffi.Float)>>('play_animation');
|
||||
late final _play_animation = _play_animationPtr.asFunction<
|
||||
void Function(ffi.Pointer<ffi.Void>, int, int, int, int, double)>();
|
||||
void Function(ffi.Pointer<ffi.Void>, int, int, int, int, int, double)>();
|
||||
|
||||
void set_animation_frame(
|
||||
ffi.Pointer<ffi.Void> assetManager,
|
||||
@@ -832,6 +822,25 @@ class NativeLibrary {
|
||||
late final _get_animation_name = _get_animation_namePtr.asFunction<
|
||||
void Function(ffi.Pointer<ffi.Void>, int, ffi.Pointer<ffi.Char>, int)>();
|
||||
|
||||
double get_animation_duration(
|
||||
ffi.Pointer<ffi.Void> assetManager,
|
||||
int asset,
|
||||
int index,
|
||||
) {
|
||||
return _get_animation_duration(
|
||||
assetManager,
|
||||
asset,
|
||||
index,
|
||||
);
|
||||
}
|
||||
|
||||
late final _get_animation_durationPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Float Function(ffi.Pointer<ffi.Void>, EntityId,
|
||||
ffi.Int)>>('get_animation_duration');
|
||||
late final _get_animation_duration = _get_animation_durationPtr
|
||||
.asFunction<double Function(ffi.Pointer<ffi.Void>, int, int)>();
|
||||
|
||||
void get_morph_target_name(
|
||||
ffi.Pointer<ffi.Void> assetManager,
|
||||
int asset,
|
||||
@@ -1195,7 +1204,7 @@ class NativeLibrary {
|
||||
late final _ios_dummy = _ios_dummyPtr.asFunction<void Function()>();
|
||||
}
|
||||
|
||||
final class __mbstate_t extends ffi.Union {
|
||||
class __mbstate_t extends ffi.Union {
|
||||
@ffi.Array.multi([128])
|
||||
external ffi.Array<ffi.Char> __mbstate8;
|
||||
|
||||
@@ -1203,7 +1212,7 @@ final class __mbstate_t extends ffi.Union {
|
||||
external int _mbstateL;
|
||||
}
|
||||
|
||||
final class __darwin_pthread_handler_rec extends ffi.Struct {
|
||||
class __darwin_pthread_handler_rec extends ffi.Struct {
|
||||
external ffi
|
||||
.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
|
||||
__routine;
|
||||
@@ -1213,7 +1222,7 @@ final class __darwin_pthread_handler_rec extends ffi.Struct {
|
||||
external ffi.Pointer<__darwin_pthread_handler_rec> __next;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_attr_t extends ffi.Struct {
|
||||
class _opaque_pthread_attr_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1221,7 +1230,7 @@ final class _opaque_pthread_attr_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_cond_t extends ffi.Struct {
|
||||
class _opaque_pthread_cond_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1229,7 +1238,7 @@ final class _opaque_pthread_cond_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_condattr_t extends ffi.Struct {
|
||||
class _opaque_pthread_condattr_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1237,7 +1246,7 @@ final class _opaque_pthread_condattr_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_mutex_t extends ffi.Struct {
|
||||
class _opaque_pthread_mutex_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1245,7 +1254,7 @@ final class _opaque_pthread_mutex_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_mutexattr_t extends ffi.Struct {
|
||||
class _opaque_pthread_mutexattr_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1253,7 +1262,7 @@ final class _opaque_pthread_mutexattr_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_once_t extends ffi.Struct {
|
||||
class _opaque_pthread_once_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1261,7 +1270,7 @@ final class _opaque_pthread_once_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_rwlock_t extends ffi.Struct {
|
||||
class _opaque_pthread_rwlock_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1269,7 +1278,7 @@ final class _opaque_pthread_rwlock_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_rwlockattr_t extends ffi.Struct {
|
||||
class _opaque_pthread_rwlockattr_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1277,7 +1286,7 @@ final class _opaque_pthread_rwlockattr_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class _opaque_pthread_t extends ffi.Struct {
|
||||
class _opaque_pthread_t extends ffi.Struct {
|
||||
@ffi.Long()
|
||||
external int __sig;
|
||||
|
||||
@@ -1287,7 +1296,7 @@ final class _opaque_pthread_t extends ffi.Struct {
|
||||
external ffi.Array<ffi.Char> __opaque;
|
||||
}
|
||||
|
||||
final class ResourceBuffer extends ffi.Struct {
|
||||
class ResourceBuffer extends ffi.Struct {
|
||||
external ffi.Pointer<ffi.Void> data;
|
||||
|
||||
@ffi.Uint32()
|
||||
@@ -1297,7 +1306,7 @@ final class ResourceBuffer extends ffi.Struct {
|
||||
external int id;
|
||||
}
|
||||
|
||||
final class ResourceLoaderWrapper extends ffi.Struct {
|
||||
class ResourceLoaderWrapper extends ffi.Struct {
|
||||
external LoadResource mLoadResource;
|
||||
|
||||
external FreeResource mFreeResource;
|
||||
|
||||
Reference in New Issue
Block a user