diff --git a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt index 8e21616ea1..8e5939fe39 100644 --- a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt +++ b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt @@ -179,7 +179,7 @@ class ModelViewer( asset = assetLoader.createAsset(buffer) asset?.let { asset -> resourceLoader.asyncBeginLoad(asset) - animator = asset.animator + animator = asset.getInstance().animator asset.releaseSourceData() } } @@ -202,7 +202,7 @@ class ModelViewer( resourceLoader.addResourceData(uri, resourceBuffer) } resourceLoader.asyncBeginLoad(asset) - animator = asset.animator + animator = asset.getInstance().animator asset.releaseSourceData() } } @@ -359,7 +359,7 @@ class ModelViewer( resourceLoader.addResourceData(uri, buffer) } resourceLoader.asyncBeginLoad(asset) - animator = asset.animator + animator = asset.getInstance().animator asset.releaseSourceData() } } diff --git a/android/gltfio-android/src/main/cpp/FilamentAsset.cpp b/android/gltfio-android/src/main/cpp/FilamentAsset.cpp index f32ecebb9e..866bd4cc3a 100644 --- a/android/gltfio-android/src/main/cpp/FilamentAsset.cpp +++ b/android/gltfio-android/src/main/cpp/FilamentAsset.cpp @@ -172,27 +172,6 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetCameraEntityCount(JNIE return asset->getCameraEntityCount(); } -extern "C" JNIEXPORT jint JNICALL -Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialInstanceCount(JNIEnv*, jclass, - jlong nativeAsset) { - FilamentAsset* asset = (FilamentAsset*) nativeAsset; - return asset->getMaterialInstanceCount(); -} - -extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialInstances(JNIEnv* env, jclass, - jlong nativeAsset, jlongArray result) { - FilamentAsset* asset = (FilamentAsset*) nativeAsset; - jsize available = env->GetArrayLength(result); - jsize count = std::min(available, (jsize) asset->getMaterialInstanceCount()); - jlong* dst = env->GetLongArrayElements(result, nullptr); - const MaterialInstance * const* src = asset->getMaterialInstances(); - for (jsize i = 0; i < count; i++) { - dst[i] = (jlong) src[i]; - } - env->ReleaseLongArrayElements(result, dst, 0); -} - extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_gltfio_FilamentAsset_nGetBoundingBox(JNIEnv* env, jclass, jlong nativeAsset, jfloatArray result) { @@ -229,10 +208,10 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jc } extern "C" JNIEXPORT jlong JNICALL -Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass, +Java_com_google_android_filament_gltfio_FilamentAsset_nGetInstance(JNIEnv* , jclass, jlong nativeAsset) { FilamentAsset* asset = (FilamentAsset*) nativeAsset; - return (jlong) asset->getAnimator(); + return (jlong) asset->getInstance(); } extern "C" JNIEXPORT jint JNICALL @@ -272,30 +251,6 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNames(JNIEn } } -extern "C" JNIEXPORT jint JNICALL -Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantCount(JNIEnv*, jclass, - jlong nativeAsset) { - FilamentAsset* asset = (FilamentAsset*) nativeAsset; - return (jint) asset->getMaterialVariantCount(); -} - -extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantNames(JNIEnv* env, jclass, - jlong nativeAsset, jobjectArray result) { - FilamentAsset* asset = (FilamentAsset*) nativeAsset; - for (int i = 0; i < asset->getMaterialVariantCount(); ++i) { - const char* name = asset->getMaterialVariantName(i); - env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name)); - } -} - -extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_gltfio_FilamentAsset_nApplyMaterialVariant(JNIEnv* env, jclass, - jlong nativeAsset, jint variantIndex) { - FilamentAsset* asset = (FilamentAsset*) nativeAsset; - asset->applyMaterialVariant(variantIndex); -} - extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv* env, jclass, jlong nativeAsset) { diff --git a/android/gltfio-android/src/main/cpp/FilamentInstance.cpp b/android/gltfio-android/src/main/cpp/FilamentInstance.cpp index c35876681d..62d048987e 100644 --- a/android/gltfio-android/src/main/cpp/FilamentInstance.cpp +++ b/android/gltfio-android/src/main/cpp/FilamentInstance.cpp @@ -20,6 +20,7 @@ #include +using namespace filament; using namespace filament::gltfio; using namespace utils; @@ -62,6 +63,44 @@ Java_com_google_android_filament_gltfio_FilamentInstance_nApplyMaterialVariant(J instance->applyMaterialVariant(variantIndex); } +extern "C" JNIEXPORT jint JNICALL +Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialVariantCount(JNIEnv*, jclass, + jlong nativeInstance) { + FilamentInstance* instance = (FilamentInstance*) nativeInstance; + return (jint) instance->getMaterialVariantCount(); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialVariantNames(JNIEnv* env, jclass, + jlong nativeInstance, jobjectArray result) { + FilamentInstance* instance = (FilamentInstance*) nativeInstance; + for (int i = 0; i < instance->getMaterialVariantCount(); ++i) { + const char* name = instance->getMaterialVariantName(i); + env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name)); + } +} + +extern "C" JNIEXPORT jint JNICALL +Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialInstanceCount(JNIEnv*, jclass, + jlong nativeInstance) { + FilamentInstance* instance = (FilamentInstance*) nativeInstance; + return instance->getMaterialInstanceCount(); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialInstances(JNIEnv* env, jclass, + jlong nativeInstance, jlongArray result) { + FilamentInstance* instance = (FilamentInstance*) nativeInstance; + jsize available = env->GetArrayLength(result); + jsize count = std::min(available, (jsize) instance->getMaterialInstanceCount()); + jlong* dst = env->GetLongArrayElements(result, nullptr); + const MaterialInstance * const* src = instance->getMaterialInstances(); + for (jsize i = 0; i < count; i++) { + dst[i] = (jlong) src[i]; + } + env->ReleaseLongArrayElements(result, dst, 0); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_gltfio_FilamentInstance_nAttachSkin(JNIEnv* env, jclass, jlong nativeInstance, jint skinIndex, jint targetEntity) { 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 2f830d38c5..20bc86aa5e 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 @@ -23,7 +23,6 @@ import androidx.annotation.Nullable; import com.google.android.filament.Box; import com.google.android.filament.Engine; import com.google.android.filament.Entity; -import com.google.android.filament.MaterialInstance; /** * Owns a bundle of Filament objects that have been created by AssetLoader. @@ -35,25 +34,32 @@ import com.google.android.filament.MaterialInstance; * NameComponentManager, RenderableManager, and others.

* *

In addition to the aforementioned entities, an asset has strong ownership over a list of - * VertexBuffer, IndexBuffer, MaterialInstance, and - * Texture.

+ * VertexBuffer, IndexBuffer, and Texture.

* *

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

* * @see ResourceLoader - * @see Animator + * @see FilamentInstance * @see AssetLoader */ public class FilamentAsset { private long mNativeObject; - private Animator mAnimator; + private FilamentInstance mPrimaryInstance; private Engine mEngine; FilamentAsset(Engine engine, long nativeObject) { mEngine = engine; mNativeObject = nativeObject; - mAnimator = null; + } + + public FilamentInstance getInstance() { + if (mPrimaryInstance != null) { + return mPrimaryInstance; + } + long nativeInstance = nGetInstance(getNativeObject()); + mPrimaryInstance = new FilamentInstance(this, nativeInstance); + return mPrimaryInstance; } long getNativeObject() { @@ -169,17 +175,6 @@ public class FilamentAsset { return result; } - public @NonNull MaterialInstance[] getMaterialInstances() { - final int count = nGetMaterialInstanceCount(mNativeObject); - MaterialInstance[] result = new MaterialInstance[count]; - long[] natives = new long[count]; - nGetMaterialInstances(mNativeObject, natives); - for (int i = 0; i < count; i++) { - result[i] = new MaterialInstance(mEngine, natives[i]); - } - return result; - } - /** * Gets the bounding box computed from the supplied min / max values in glTF accessors. * @@ -209,25 +204,6 @@ public class FilamentAsset { return nGetExtras(mNativeObject, entity); } - /** - * Retrieves the Animator interface for this asset. - * - *

When calling this for the first time, this must be called after - * {@link ResourceLoader#loadResources} or {@link ResourceLoader#asyncBeginLoad}. When the asset - * is destroyed, its animator becomes invalid.

- */ - public @NonNull Animator getAnimator() { - if (mAnimator != null) { - return mAnimator; - } - long nativeAnimator = nGetAnimator(getNativeObject()); - if (nativeAnimator == 0) { - throw new IllegalStateException("Unable to create animator"); - } - mAnimator = new Animator(nativeAnimator); - return mAnimator; - } - /** * Gets the names of all morph targets in the given entity. */ @@ -246,31 +222,6 @@ public class FilamentAsset { return uris; } - /** - * Returns the names of all material variants. - */ - public @NonNull String[] getMaterialVariantNames() { - String[] names = new String[nGetMaterialVariantCount(mNativeObject)]; - nGetMaterialVariantNames(mNativeObject, names); - return names; - } - - /** - * Applies the given material variant to all primitives that it affects. - * - * This is efficient because it merely swaps around persistent MaterialInstances. If you change - * a material parameter while a certain variant is active, the updated value will be remembered - * after you re-apply that variant. - * - * If the asset is instanced, this affects all instances in the same way. - * To set the variant on an individual instance, use FilamentInstance#applyMaterialVariant. - * - * Ignored if variantIndex is out of bounds. - */ - public void applyMaterialVariant(@IntRange(from = 0) int variantIndex) { - nApplyMaterialVariant(getNativeObject(), variantIndex); - } - /** * Reclaims CPU-side memory for URI strings, binding lists, and raw animation data. * @@ -282,8 +233,10 @@ public class FilamentAsset { nReleaseSourceData(mNativeObject); } + public Engine getEngine() { return mEngine; } + void clearNativeObject() { - if (mAnimator != null) mAnimator.clearNativeObject(); + mPrimaryInstance = null; mNativeObject = 0; } @@ -307,21 +260,17 @@ public class FilamentAsset { private static native int nGetCameraEntityCount(long nativeAsset); private static native void nGetCameraEntities(long nativeAsset, int[] result); - private static native int nGetMaterialInstanceCount(long nativeAsset); - private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults); - - private static native int nGetMaterialVariantCount(long nativeAsset); - private static native void nGetMaterialVariantNames(long nativeAsset, String[] result); - private static native int nGetMorphTargetCount(long nativeAsset, int entity); private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result); private static native void nGetBoundingBox(long nativeAsset, float[] box); private static native String nGetName(long nativeAsset, int entity); private static native String nGetExtras(long nativeAsset, int entity); - private static native long nGetAnimator(long nativeAsset); - private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex); + + private static native long nGetInstance(long nativeAsset); + private static native int nGetResourceUriCount(long nativeAsset); private static native void nGetResourceUris(long nativeAsset, String[] result); + private static native void nReleaseSourceData(long nativeAsset); } diff --git a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentInstance.java b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentInstance.java index 48e288d4c1..71d286cda8 100644 --- a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentInstance.java +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/FilamentInstance.java @@ -19,7 +19,9 @@ package com.google.android.filament.gltfio; import androidx.annotation.IntRange; import androidx.annotation.NonNull; +import com.google.android.filament.Engine; import com.google.android.filament.Entity; +import com.google.android.filament.MaterialInstance; /** * Provides access to a hierarchy of entities that have been instanced from a glTF asset. @@ -146,11 +148,39 @@ public class FilamentInstance { nApplyMaterialVariant(mNativeObject, variantIndex); } + public @NonNull MaterialInstance[] getMaterialInstances() { + final int count = nGetMaterialInstanceCount(mNativeObject); + MaterialInstance[] result = new MaterialInstance[count]; + long[] natives = new long[count]; + nGetMaterialInstances(mNativeObject, natives); + Engine engine = mAsset.getEngine(); + for (int i = 0; i < count; i++) { + result[i] = new MaterialInstance(engine, natives[i]); + } + return result; + } + + /** + * Returns the names of all material variants. + */ + public @NonNull String[] getMaterialVariantNames() { + String[] names = new String[nGetMaterialVariantCount(mNativeObject)]; + nGetMaterialVariantNames(mNativeObject, names); + return names; + } + private static native int nGetRoot(long nativeInstance); private static native int nGetEntityCount(long nativeInstance); private static native void nGetEntities(long nativeInstance, int[] result); private static native long nGetAnimator(long nativeInstance); + + private static native int nGetMaterialInstanceCount(long nativeAsset); + private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults); + private static native void nApplyMaterialVariant(long nativeInstance, int variantIndex); + private static native int nGetMaterialVariantCount(long nativeAsset); + private static native void nGetMaterialVariantNames(long nativeAsset, String[] result); + private static native void nGetJointsAt(long nativeInstance, int skinIndex, int[] result); private static native int nGetSkinCount(long nativeInstance); private static native void nGetSkinNames(long nativeInstance, String[] result); diff --git a/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt b/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt index 1a2d2cb359..6e449261fd 100644 --- a/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt +++ b/android/samples/sample-gltf-viewer/src/main/java/com/google/android/filament/gltf/MainActivity.kt @@ -417,7 +417,7 @@ class MainActivity : Activity() { // Just for testing purposes, this releases the current model and reloads the default model. inner class DoubleTapListener : GestureDetector.SimpleOnGestureListener() { - override fun onDoubleTap(e: MotionEvent?): Boolean { + override fun onDoubleTap(e: MotionEvent): Boolean { modelViewer.destroyModel() createDefaultRenderables() return super.onDoubleTap(e)