From 8c36e6d95f48b6915ac0b2fdc7fb7302a76f4e64 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Wed, 28 Jul 2021 18:58:41 +0200 Subject: [PATCH] MaterialKey: expose constrainMaterial to Android (#4398) --- .../src/main/cpp/MaterialKey.cpp | 36 ++++++++++++++++--- .../filament/gltfio/MaterialProvider.java | 18 ++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/android/gltfio-android/src/main/cpp/MaterialKey.cpp b/android/gltfio-android/src/main/cpp/MaterialKey.cpp index d3c63d36e0..554368fb7a 100644 --- a/android/gltfio-android/src/main/cpp/MaterialKey.cpp +++ b/android/gltfio-android/src/main/cpp/MaterialKey.cpp @@ -69,11 +69,6 @@ void MaterialKeyHelper::init(JNIEnv* env) { hasIOR = field("hasIOR", "Z"); } -extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) { - MaterialKeyHelper::get().init(env); -} - void MaterialKeyHelper::copy(JNIEnv* env, MaterialKey& dst, jobject src) { dst.doubleSided = env->GetBooleanField(src, doubleSided); dst.unlit = env->GetBooleanField(src, unlit); @@ -149,3 +144,34 @@ void MaterialKeyHelper::copy(JNIEnv* env, jobject dst, const MaterialKey& src) { env->SetBooleanField(dst, hasSheen, src.hasSheen); env->SetBooleanField(dst, hasIOR, src.hasIOR); } + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) { + MaterialKeyHelper::get().init(env); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nConstrainMaterial(JNIEnv* env, jclass, + jobject materialKey, jintArray uvMap) { + MaterialKey nativeMaterialKey = {}; + + auto& helper = MaterialKeyHelper::get(); + helper.copy(env, nativeMaterialKey, materialKey); + + UvMap nativeUvMap = {}; + constrainMaterial(&nativeMaterialKey, &nativeUvMap); + + // Copy the UvMap results from the native array into the JVM array. + jint* elements = env->GetIntArrayElements(uvMap, nullptr); + if (elements) { + const size_t javaSize = env->GetArrayLength(uvMap); + for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) { + elements[i] = nativeUvMap[i]; + } + env->ReleaseIntArrayElements(uvMap, elements, 0); + } + + // The config parameter is an in-out parameter so we need to copy the results back to Java. + helper.copy(env, materialKey, nativeMaterialKey); +} diff --git a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java index 8da62c8e26..92557a6625 100644 --- a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java @@ -71,7 +71,25 @@ public interface MaterialProvider { static { nGlobalInit(); } + + /** + * Populate UV map according to the material key, altering latter if required. + * + * Filament supports up to 2 UV sets. glTF has arbitrary texcoord set indices, but it + * allows implementations to support only 2 simultaneous sets. Here we build a mapping + * table with 1-based indices where 0 means unused. Note that the order in which we drop + * textures can affect the look of certain assets. This "order of degradation" is + * stipulated by the glTF 2.0 specification. + * + * @param uvmap Output argument that gets populated with a small table that maps from a + * glTF uv index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1). + */ + public void constrainMaterial(@NonNull @Size(min = 8) int[] uvmap) { + nConstrainMaterial(this, uvmap); + } + private static native void nGlobalInit(); + private static native void nConstrainMaterial(MaterialKey materialKey, int[] uvmap); }; /**