diff --git a/android/gltfio-android/src/main/cpp/Animator.cpp b/android/gltfio-android/src/main/cpp/Animator.cpp index eade9634de8..94cfd73e5b8 100644 --- a/android/gltfio-android/src/main/cpp/Animator.cpp +++ b/android/gltfio-android/src/main/cpp/Animator.cpp @@ -17,12 +17,27 @@ #include #include +#include using namespace filament; using namespace filament::math; using namespace filament::gltfio; using namespace utils; +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_gltfio_Animator_nCreateAnimatorFromAssetAndInstance(JNIEnv*, jclass, jlong nativeAsset, jlong nativeInstance) { + FilamentAsset* asset = (FilamentAsset*) nativeAsset; + FilamentInstance* instance = (FilamentInstance*) nativeInstance; + Animator* animator = new Animator(asset, instance); + return (jlong)animator; +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_Animator_nDestroyAnimator(JNIEnv*, jclass, jlong nativeAnimator) { + Animator* animator = (Animator*) nativeAnimator; + delete animator; +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_gltfio_Animator_nApplyAnimation(JNIEnv*, jclass, jlong nativeAnimator, jint index, jfloat time) { diff --git a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/Animator.java b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/Animator.java index cf2e86f071a..6add0c5d611 100644 --- a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/Animator.java +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/Animator.java @@ -37,11 +37,30 @@ */ public class Animator { private long mNativeObject; + private Boolean mIsOwner = false; Animator(long nativeObject) { mNativeObject = nativeObject; } + public Animator(FilamentAsset asset, FilamentInstance instance) { + mNativeObject = nCreateAnimatorFromAssetAndInstance(asset.getNativeObject(), instance.getNativeObject()); + mIsOwner = true; + } + + @Override + public void finalize() { + try { + super.finalize(); + } catch (Throwable t) { // Ignore + } finally { + if (mIsOwner) { + nDestroyAnimator(mNativeObject); + mNativeObject = 0; + } + } + } + /** * Applies rotation, translation, and scale to entities that have been targeted by the given * animation definition. Uses TransformManager. @@ -137,6 +156,8 @@ void clearNativeObject() { mNativeObject = 0; } + private static native long nCreateAnimatorFromAssetAndInstance(long nativeAsset, long nativeInstance); + private static native void nDestroyAnimator(long nativeAnimator); private static native void nApplyAnimation(long nativeAnimator, int index, float time); private static native void nUpdateBoneMatrices(long nativeAnimator); private static native void nApplyCrossFade(long nativeAnimator, int animIndex, float animTime, float alpha); diff --git a/libs/gltfio/include/gltfio/Animator.h b/libs/gltfio/include/gltfio/Animator.h index 199555a40d3..fda05db29fc 100644 --- a/libs/gltfio/include/gltfio/Animator.h +++ b/libs/gltfio/include/gltfio/Animator.h @@ -97,6 +97,14 @@ class UTILS_PUBLIC Animator { // For internal use only. void addInstance(FFilamentInstance* instance); + /** Creates an Animator that will use the corresponding asset and instance, + * can be used to animate an instance with animation from another asset. + * When used, the caller is responsible for deleting it. + * The normal way of getting an Animator is to call FilamentInstance::getAnimator(). + */ + Animator(FilamentAsset *asset, FilamentInstance *instance); + ~Animator(); + private: /*! \cond PRIVATE */ @@ -106,7 +114,6 @@ class UTILS_PUBLIC Animator { // If "instance" is null, then this is the primary animator. Animator(FFilamentAsset const* asset, FFilamentInstance* instance); - ~Animator(); Animator(const Animator& animator) = delete; Animator(Animator&& animator) = delete; diff --git a/libs/gltfio/src/Animator.cpp b/libs/gltfio/src/Animator.cpp index 6e53b705c60..af1cc107e51 100644 --- a/libs/gltfio/src/Animator.cpp +++ b/libs/gltfio/src/Animator.cpp @@ -254,6 +254,9 @@ void Animator::addInstance(FFilamentInstance* instance) { } } +Animator::Animator(FilamentAsset *asset, FilamentInstance *instance) : Animator(reinterpret_cast(asset), reinterpret_cast(instance)) { +} + Animator::~Animator() { delete mImpl; } @@ -437,7 +440,6 @@ void AnimatorImpl::applyAnimation(const Channel& channel, float t, size_t prevIn const TimeValues& times = sampler->times; TrsTransformManager::Instance trsNode = trsTransformManager->getInstance(channel.targetEntity); TransformManager::Instance node = transformManager->getInstance(channel.targetEntity); - switch (channel.transformType) { case Channel::SCALE: { @@ -561,9 +563,11 @@ void AnimatorImpl::updateBoneMatrices(FFilamentInstance* instance) { } for (size_t boneIndex = 0; boneIndex < njoints; ++boneIndex) { const auto& joint = skin.joints[boneIndex]; + assert_invariant(assetSkin.inverseBindMatrices.size() > boneIndex); const mat4f& inverseBindMatrix = assetSkin.inverseBindMatrices[boneIndex]; TransformManager::Instance jointInstance = transformManager->getInstance(joint); mat4 globalJointTransform = transformManager->getWorldTransformAccurate(jointInstance); + assert_invariant(boneMatrices.size() > boneIndex); boneMatrices[boneIndex] = mat4f{ inverseGlobalTransform * globalJointTransform } * inverseBindMatrix;