From 618b59932cfd9dc95d946cc1c9897730bc5639ea Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Thu, 24 Oct 2019 13:52:10 -0700 Subject: [PATCH] gltfio: Add Java / Kotlin bindings for Animator. Fixes #1529. --- RELEASE_NOTES.md | 4 + android/gltfio-android/CMakeLists.txt | 1 + .../gltfio-android/src/main/cpp/Animator.cpp | 59 ++++++++++ .../src/main/cpp/FilamentAsset.cpp | 7 ++ .../android/filament/gltfio/Animator.java | 103 ++++++++++++++++++ .../android/filament/gltfio/AssetLoader.java | 3 + .../filament/gltfio/FilamentAsset.java | 22 +++- 7 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 android/gltfio-android/src/main/cpp/Animator.cpp create mode 100644 android/gltfio-android/src/main/java/com/google/android/filament/gltfio/Animator.java diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 45ac955a91..4802b9dbd8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -3,6 +3,10 @@ This file contains one line summaries of commits that are worthy of mentioning in release notes. A new header is inserted each time a *tag* is created. +## Next release + +- Add Java / Kotlin bindings for gltfio::Animator. + ## v1.4.1 - Added missing API documentation. diff --git a/android/gltfio-android/CMakeLists.txt b/android/gltfio-android/CMakeLists.txt index 77fef27c7d..c8ad30a405 100644 --- a/android/gltfio-android/CMakeLists.txt +++ b/android/gltfio-android/CMakeLists.txt @@ -66,6 +66,7 @@ set(CMAKE_SHARED_LINKER_FLAGS " ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic-func set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libgltfio-jni.map") add_library(gltfio-jni SHARED + src/main/cpp/Animator.cpp src/main/cpp/AssetLoader.cpp src/main/cpp/FilamentAsset.cpp src/main/cpp/KtxLoader.cpp diff --git a/android/gltfio-android/src/main/cpp/Animator.cpp b/android/gltfio-android/src/main/cpp/Animator.cpp new file mode 100644 index 0000000000..e1e42a2514 --- /dev/null +++ b/android/gltfio-android/src/main/cpp/Animator.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +using namespace filament; +using namespace filament::math; +using namespace gltfio; +using namespace utils; + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_Animator_nApplyAnimation(JNIEnv*, jclass, jlong nativeAnimator, + jint index, jfloat time) { + Animator* animator = (Animator*) nativeAnimator; + animator->applyAnimation(index, time); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_Animator_nUpdateBoneMatrices(JNIEnv*, jclass, jlong nativeAnimator) { + Animator* animator = (Animator*) nativeAnimator; + animator->updateBoneMatrices(); +} + +extern "C" JNIEXPORT jint JNICALL +Java_com_google_android_filament_gltfio_Animator_nGetAnimationCount(JNIEnv*, jclass, jlong nativeAnimator) { + Animator* animator = (Animator*) nativeAnimator; + return animator->getAnimationCount(); +} + +extern "C" JNIEXPORT float JNICALL +Java_com_google_android_filament_gltfio_Animator_nGetAnimationDuration(JNIEnv*, jclass, + jlong nativeAnimator, jint index) { + Animator* animator = (Animator*) nativeAnimator; + return animator->getAnimationDuration(index); +} + +extern "C" JNIEXPORT jstring JNICALL +Java_com_google_android_filament_gltfio_Animator_nGetAnimationName(JNIEnv* env, jclass, + jlong nativeAnimator, jint index) { + Animator* animator = (Animator*) nativeAnimator; + const char* val = animator->getAnimationName(index); + return val ? env->NewStringUTF(val) : nullptr; + +} diff --git a/android/gltfio-android/src/main/cpp/FilamentAsset.cpp b/android/gltfio-android/src/main/cpp/FilamentAsset.cpp index e0007de8f0..aa4f7455a7 100644 --- a/android/gltfio-android/src/main/cpp/FilamentAsset.cpp +++ b/android/gltfio-android/src/main/cpp/FilamentAsset.cpp @@ -71,3 +71,10 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetName(JNIEnv* env, jcla const char* val = asset->getName(*entity); return val ? env->NewStringUTF(val) : nullptr; } + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* env, jclass, + jlong nativeAsset) { + FilamentAsset* asset = (FilamentAsset*) nativeAsset; + return (jlong) asset->getAnimator(); +} 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 new file mode 100644 index 0000000000..ad94ad2424 --- /dev/null +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/Animator.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.filament.gltfio; + +import android.support.annotation.IntRange; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * Updates matrices according to glTF animation and skin definitions. + * + *

Animator can be used for two things: + *

    + *
  • Updating matrices in TransformManager components according to glTF animation definitions.
  • + *
  • Updating bone matrices in RenderableManager components according to glTF skin definitions.
  • + *
+ *

+ * + * @see AssetLoader + * @see FilamentAsset + * @see ResourceLoader + */ +public class Animator { + private long mNativeObject; + + Animator(long nativeObject) { + mNativeObject = nativeObject; + } + + /** + * Applies rotation, translation, and scale to entities that have been targeted by the given + * animation definition. Uses TransformManager. + * + * @param animationIndex Zero-based index for the animation of interest. + * @param time Elapsed time of interest in seconds. + * + * @see #getAnimationCount + */ + public void applyAnimation(@IntRange(from = 0) int animationIndex, float time) { + nApplyAnimation(mNativeObject, animationIndex, time); + } + + /** + * Computes root-to-node transforms for all bone nodes, then passes + * the results into {@see RenderableManager#setBones}. + * Uses TransformManager and RenderableManager. + * + *

NOTE: this operation is independent of animation.

+ */ + public void updateBoneMatrices() { + nUpdateBoneMatrices(mNativeObject); + } + + /** + * Returns the number of animation definitions in the glTF asset. + */ + public int getAnimationCount() { + return nGetAnimationCount(mNativeObject); + } + + /** + * Returns the duration of the specified glTF animation in seconds. + * + * @param animationIndex Zero-based index for the animation of interest. + * + * @see #getAnimationCount + * */ + public float getAnimationDuration(@IntRange(from = 0) int animationIndex) { + return nGetAnimationDuration(mNativeObject, animationIndex); + } + + /** + * Returns a weak reference to the string name of the specified animation, or an + * empty string if none was specified. + * + * @param animationIndex Zero-based index for the animation of interest. + * + * @see #getAnimationCount + */ + public String getAnimationName(@IntRange(from = 0) int animationIndex) { + return nGetAnimationName(mNativeObject, animationIndex); + } + + private static native void nApplyAnimation(long nativeAnimator, int index, float time); + private static native void nUpdateBoneMatrices(long nativeAnimator); + private static native int nGetAnimationCount(long nativeAnimator); + private static native float nGetAnimationDuration(long nativeAnimator, int index); + private static native String nGetAnimationName(long nativeAnimator, int index); +} diff --git a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/AssetLoader.java b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/AssetLoader.java index 8a50d96cf2..41182db809 100644 --- a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/AssetLoader.java +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/AssetLoader.java @@ -55,10 +55,13 @@ import java.nio.Buffer; * } * * ResourceLoader(engine).loadResources(filamentAsset).destroy() + * animator = asset.getAnimator() + * * scene.addEntities(filamentAsset.entities) * } * * + * @see Animator * @see FilamentAsset * @see ResourceLoader */ diff --git a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentAsset.java b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentAsset.java index e653994f14..b3abd71c43 100644 --- a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentAsset.java +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentAsset.java @@ -37,16 +37,17 @@ import com.google.android.filament.Entity; *

Clients can use {@link ResourceLoader} to create textures, compute tangent quaternions, and * upload data into vertex buffers and index buffers.

* - *

TODO: Animator is not yet exposed to Java / Kotlin clients.

- * * @see ResourceLoader + * @see Animator * @see AssetLoader */ public class FilamentAsset { private long mNativeObject; + private Animator mAnimator; FilamentAsset(long nativeObject) { mNativeObject = nativeObject; + mAnimator = null; } long getNativeObject() { @@ -82,12 +83,26 @@ public class FilamentAsset { } /** - * Gets the NameComponentManager label for the given entity, if it exists. + * Gets the NameComponentManager label for the given entity, if it exists. */ public String getName(@Entity int entity) { return nGetName(getNativeObject(), entity); } + /** + * Creates or retrieves the Animator for this asset. + * + *

When calling this for the first time, this must be called after + * {@see ResourceLoader#loadResources}.

+ */ + public Animator getAnimator() { + if (mAnimator != null) { + return mAnimator; + } + mAnimator = new Animator(nGetAnimator(getNativeObject())); + return mAnimator; + } + void clearNativeObject() { mNativeObject = 0; } @@ -97,4 +112,5 @@ public class FilamentAsset { private static native void nGetEntities(long nativeAsset, int[] result); private static native void nGetBoundingBox(long nativeAsset, float[] box); private static native String nGetName(long nativeAsset, int entity); + private static native long nGetAnimator(long nativeAsset); }