Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to play animations on a separate instance #7919

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions android/gltfio-android/src/main/cpp/Animator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,27 @@
#include <jni.h>

#include <gltfio/Animator.h>
#include <gltfio/FilamentInstance.h>

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,30 @@
*/
public class Animator {
private long mNativeObject;
private Boolean mIsOwner = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be lower case boolean, otherwise it's an object.


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;
}
}
}
Comment on lines +51 to +62
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this -- I think we can't rely on finalizers from being called. I'm not sure what the correct pattern would be here. @romainguy what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finalizers are unfortunately not reliable (and at best take a lot of time to be invoked). We did use them in a couple of places but it's better to have a manual destroy().


/**
* Applies rotation, translation, and scale to entities that have been targeted by the given
* animation definition. Uses <code>TransformManager</code>.
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 8 additions & 1 deletion libs/gltfio/include/gltfio/Animator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion libs/gltfio/src/Animator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ void Animator::addInstance(FFilamentInstance* instance) {
}
}

Animator::Animator(FilamentAsset *asset, FilamentInstance *instance) : Animator(reinterpret_cast<FFilamentAsset*>(asset), reinterpret_cast<FFilamentInstance*>(instance)) {
}

Animator::~Animator() {
delete mImpl;
}
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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;
Expand Down
Loading