From 7fcd3e1a4f8248cf7c182fb4b88754babfa322a9 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Tue, 25 Jun 2019 14:37:33 -0700 Subject: [PATCH] Java clients can now get material instances from renderables. Discussed this feature with Mathias, we decided to create MaterialInstance Java wrappers on the fly, and create Material Java wrappers lazily. This is simple and avoids caching the wrapper objects, which might otherwise lead to complexity and bugs. Note that gltfio creates material instances behind the scenes, so this feature is particularly useful for gltfio clients. --- RELEASE_NOTES.md | 1 + .../src/main/cpp/RenderableManager.cpp | 15 +++++++++++++++ .../com/google/android/filament/Material.java | 6 +++--- .../google/android/filament/MaterialInstance.java | 11 ++++++++++- .../android/filament/RenderableManager.java | 10 ++++++++++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 298cd0fc21..830eb0b130 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,6 +6,7 @@ A new header is inserted each time a *tag* is created. # Release notes +- Added `getMaterialInstanceAt` to the Java version of RenderableManager. - Fix JNI bindings for setting values in parameter arrays. - Added JNI bindings for the gltfio library. - Fix support for parameter arrays in `.mat` files. diff --git a/android/filament-android/src/main/cpp/RenderableManager.cpp b/android/filament-android/src/main/cpp/RenderableManager.cpp index 18e722be7e..4f03667b5b 100644 --- a/android/filament-android/src/main/cpp/RenderableManager.cpp +++ b/android/filament-android/src/main/cpp/RenderableManager.cpp @@ -299,6 +299,21 @@ Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv materialInstance); } +extern "C" JNIEXPORT long JNICALL +Java_com_google_android_filament_RenderableManager_nGetMaterialInstanceAt(JNIEnv*, jclass, + jlong nativeRenderableManager, jint i, jint primitiveIndex) { + RenderableManager *rm = (RenderableManager *) nativeRenderableManager; + return (long) rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex); +} + +extern "C" JNIEXPORT long JNICALL +Java_com_google_android_filament_RenderableManager_nGetMaterialAt(JNIEnv*, jclass, + jlong nativeRenderableManager, jint i, jint primitiveIndex) { + RenderableManager *rm = (RenderableManager *) nativeRenderableManager; + MaterialInstance *mi = rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex); + return (long) mi->getMaterial(); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_RenderableManager_nSetGeometryAt__JIIIJJII(JNIEnv*, jclass, jlong nativeRenderableManager, jint i, jint primitiveIndex, jint primitiveType, diff --git a/android/filament-android/src/main/java/com/google/android/filament/Material.java b/android/filament-android/src/main/java/com/google/android/filament/Material.java index 67b58205c8..7035846727 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Material.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Material.java @@ -134,8 +134,9 @@ public class Material { } } - private Material(long nativeMaterial, long nativeDefaultInstance) { + Material(long nativeMaterial) { mNativeObject = nativeMaterial; + long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial); mDefaultInstance = new MaterialInstance(this, nativeDefaultInstance); } @@ -154,8 +155,7 @@ public class Material { public Material build(@NonNull Engine engine) { long nativeMaterial = nBuilderBuild(engine.getNativeObject(), mBuffer, mSize); if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material"); - long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial); - return new Material(nativeMaterial, nativeDefaultInstance); + return new Material(nativeMaterial); } } diff --git a/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java b/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java index 1831e1d761..8d1a5e06da 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java +++ b/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java @@ -21,8 +21,9 @@ import android.support.annotation.NonNull; import android.support.annotation.Size; public class MaterialInstance { - private final Material mMaterial; + private Material mMaterial; private long mNativeObject; + private long mNativeMaterial; public enum BooleanElement { BOOL, @@ -52,8 +53,16 @@ public class MaterialInstance { mNativeObject = nativeMaterialInstance; } + MaterialInstance(long nativeMaterial, long nativeMaterialInstance) { + mNativeMaterial = nativeMaterial; + mNativeObject = nativeMaterialInstance; + } + @NonNull public Material getMaterial() { + if (mMaterial == null) { + mMaterial = new Material(mNativeMaterial); + } return mMaterial; } diff --git a/android/filament-android/src/main/java/com/google/android/filament/RenderableManager.java b/android/filament-android/src/main/java/com/google/android/filament/RenderableManager.java index 15e7b1f281..2060398f53 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/RenderableManager.java +++ b/android/filament-android/src/main/java/com/google/android/filament/RenderableManager.java @@ -282,6 +282,14 @@ public class RenderableManager { nSetMaterialInstanceAt(mNativeObject, i, primitiveIndex, materialInstance.getNativeObject()); } + // creates a MaterialInstance Java wrapper object for a particular material instance + public @NonNull MaterialInstance getMaterialInstanceAt(@EntityInstance int i, + @IntRange(from = 0) int primitiveIndex) { + long nativeMatInstance = nGetMaterialInstanceAt(mNativeObject, i, primitiveIndex); + long nativeMaterial = nGetMaterialAt(mNativeObject, i, primitiveIndex); + return new MaterialInstance(nativeMaterial, nativeMatInstance); + } + // set/change the geometry (vertex/index buffers) of a given primitive public void setGeometryAt(@EntityInstance int i, @IntRange(from = 0) int primitiveIndex, @NonNull PrimitiveType type, @NonNull VertexBuffer vertices, @@ -356,6 +364,8 @@ public class RenderableManager { private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent); private static native int nGetPrimitiveCount(long nativeRenderableManager, int i); private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance); + private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex); + private static native long nGetMaterialAt(long nativeRenderableManager, int i, int primitiveIndex); private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count); private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, int offset, int count); private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);